nir/lower_blend: Use util enums

This avoids the silly compiler versions. Some bits are slightly more
complicated, because they have to account for inverted enum values (rather than
a separate invert bit), but this is a LOT friendlier to drivers using the pass
and it makes the pass itself more readable.

The conversion functions in panfrost/panvk will go away momentarily.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Italo Nicola <italonicola@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24076>
This commit is contained in:
Alyssa Rosenzweig
2023-07-11 07:51:03 -04:00
committed by Marge Bot
parent eb1112ae7a
commit a2d56c4c73
5 changed files with 248 additions and 130 deletions

View File

@@ -34,6 +34,7 @@
#include "compiler/nir/nir.h"
#include "compiler/nir/nir_builder.h"
#include "compiler/nir/nir_format_convert.h"
#include "util/blend.h"
#include "nir_lower_blend.h"
struct ctx {
@@ -46,19 +47,19 @@ struct ctx {
static nir_ssa_def *
nir_blend_func(
nir_builder *b,
enum blend_func func,
enum pipe_blend_func func,
nir_ssa_def *src, nir_ssa_def *dst)
{
switch (func) {
case BLEND_FUNC_ADD:
case PIPE_BLEND_ADD:
return nir_fadd(b, src, dst);
case BLEND_FUNC_SUBTRACT:
case PIPE_BLEND_SUBTRACT:
return nir_fsub(b, src, dst);
case BLEND_FUNC_REVERSE_SUBTRACT:
case PIPE_BLEND_REVERSE_SUBTRACT:
return nir_fsub(b, dst, src);
case BLEND_FUNC_MIN:
case PIPE_BLEND_MIN:
return nir_fmin(b, src, dst);
case BLEND_FUNC_MAX:
case PIPE_BLEND_MAX:
return nir_fmax(b, src, dst);
}
@@ -68,12 +69,12 @@ nir_blend_func(
/* Does this blend function multiply by a blend factor? */
static bool
nir_blend_factored(enum blend_func func)
nir_blend_factored(enum pipe_blend_func func)
{
switch (func) {
case BLEND_FUNC_ADD:
case BLEND_FUNC_SUBTRACT:
case BLEND_FUNC_REVERSE_SUBTRACT:
case PIPE_BLEND_ADD:
case PIPE_BLEND_SUBTRACT:
case PIPE_BLEND_REVERSE_SUBTRACT:
return true;
default:
return false;
@@ -102,32 +103,33 @@ nir_blend_factor_value(
nir_builder *b,
nir_ssa_def *src, nir_ssa_def *src1, nir_ssa_def *dst, nir_ssa_def *bconst,
unsigned chan,
enum blend_factor factor)
enum pipe_blendfactor factor_without_invert)
{
switch (factor) {
case BLEND_FACTOR_ZERO:
return nir_imm_floatN_t(b, 0.0, src->bit_size);
case BLEND_FACTOR_SRC_COLOR:
switch (factor_without_invert) {
case PIPE_BLENDFACTOR_ONE:
return nir_imm_floatN_t(b, 1.0, src->bit_size);
case PIPE_BLENDFACTOR_SRC_COLOR:
return nir_channel(b, src, chan);
case BLEND_FACTOR_SRC1_COLOR:
case PIPE_BLENDFACTOR_SRC1_COLOR:
return nir_channel(b, src1, chan);
case BLEND_FACTOR_DST_COLOR:
case PIPE_BLENDFACTOR_DST_COLOR:
return nir_channel(b, dst, chan);
case BLEND_FACTOR_SRC_ALPHA:
case PIPE_BLENDFACTOR_SRC_ALPHA:
return nir_channel(b, src, 3);
case BLEND_FACTOR_SRC1_ALPHA:
case PIPE_BLENDFACTOR_SRC1_ALPHA:
return nir_channel(b, src1, 3);
case BLEND_FACTOR_DST_ALPHA:
case PIPE_BLENDFACTOR_DST_ALPHA:
return nir_channel(b, dst, 3);
case BLEND_FACTOR_CONSTANT_COLOR:
case PIPE_BLENDFACTOR_CONST_COLOR:
return nir_channel(b, bconst, chan);
case BLEND_FACTOR_CONSTANT_ALPHA:
case PIPE_BLENDFACTOR_CONST_ALPHA:
return nir_channel(b, bconst, 3);
case BLEND_FACTOR_SRC_ALPHA_SATURATE:
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
return nir_alpha_saturate(b, src, dst, chan);
default:
assert(util_blendfactor_is_inverted(factor_without_invert));
unreachable("Unexpected inverted factor");
}
unreachable("Invalid blend factor");
}
static nir_ssa_def *
@@ -154,49 +156,62 @@ nir_fsat_to_format(nir_builder *b, nir_ssa_def *x, enum pipe_format format)
* clamping a blend factor is needed.
*/
static bool
should_clamp_factor(enum blend_factor factor, bool inverted, bool snorm)
should_clamp_factor(enum pipe_blendfactor factor, bool snorm)
{
switch (factor) {
case BLEND_FACTOR_ZERO:
switch (util_blendfactor_without_invert(factor)) {
case PIPE_BLENDFACTOR_ONE:
/* 0, 1 are in [0, 1] and [-1, 1] */
return false;
case BLEND_FACTOR_SRC_COLOR:
case BLEND_FACTOR_SRC1_COLOR:
case BLEND_FACTOR_DST_COLOR:
case BLEND_FACTOR_SRC_ALPHA:
case BLEND_FACTOR_SRC1_ALPHA:
case BLEND_FACTOR_DST_ALPHA:
case PIPE_BLENDFACTOR_SRC_COLOR:
case PIPE_BLENDFACTOR_SRC1_COLOR:
case PIPE_BLENDFACTOR_DST_COLOR:
case PIPE_BLENDFACTOR_SRC_ALPHA:
case PIPE_BLENDFACTOR_SRC1_ALPHA:
case PIPE_BLENDFACTOR_DST_ALPHA:
/* Colours are already clamped. For unorm, the complement of something
* clamped is still clamped. But for snorm, this is not true. Clamp for
* snorm only.
*/
return inverted && snorm;
return util_blendfactor_is_inverted(factor) && snorm;
case BLEND_FACTOR_CONSTANT_COLOR:
case BLEND_FACTOR_CONSTANT_ALPHA:
case PIPE_BLENDFACTOR_CONST_COLOR:
case PIPE_BLENDFACTOR_CONST_ALPHA:
/* Constant colours are not yet clamped */
return true;
case BLEND_FACTOR_SRC_ALPHA_SATURATE:
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
/* For unorm, this is in bounds (and hence so is its complement). For
* snorm, it may not be.
*/
return snorm;
default:
unreachable("invalid blend factor");
}
unreachable("invalid blend factor");
}
static bool
channel_uses_dest(nir_lower_blend_channel chan)
{
return chan.src_factor == BLEND_FACTOR_DST_COLOR ||
chan.src_factor == BLEND_FACTOR_DST_ALPHA ||
chan.src_factor == BLEND_FACTOR_SRC_ALPHA_SATURATE ||
!(chan.dst_factor == BLEND_FACTOR_ZERO && !chan.invert_dst_factor) ||
chan.func == BLEND_FUNC_MIN ||
chan.func == BLEND_FUNC_MAX;
/* If blend factors are ignored, dest is used (min/max) */
if (!nir_blend_factored(chan.func))
return true;
/* If dest has a nonzero factor, it is used */
if (chan.dst_factor != PIPE_BLENDFACTOR_ZERO)
return true;
/* Else, check the source factor */
switch (util_blendfactor_without_invert(chan.src_factor)) {
case PIPE_BLENDFACTOR_DST_COLOR:
case PIPE_BLENDFACTOR_DST_ALPHA:
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
return true;
default:
return false;
}
}
static nir_ssa_def *
@@ -205,17 +220,17 @@ nir_blend_factor(
nir_ssa_def *raw_scalar,
nir_ssa_def *src, nir_ssa_def *src1, nir_ssa_def *dst, nir_ssa_def *bconst,
unsigned chan,
enum blend_factor factor,
bool inverted,
enum pipe_blendfactor factor,
enum pipe_format format)
{
nir_ssa_def *f =
nir_blend_factor_value(b, src, src1, dst, bconst, chan, factor);
nir_blend_factor_value(b, src, src1, dst, bconst, chan,
util_blendfactor_without_invert(factor));
if (inverted)
if (util_blendfactor_is_inverted(factor))
f = nir_fadd_imm(b, nir_fneg(b, f), 1.0);
if (should_clamp_factor(factor, inverted, util_format_is_snorm(format)))
if (should_clamp_factor(factor, util_format_is_snorm(format)))
f = nir_fsat_to_format(b, f, format);
return nir_fmul(b, raw_scalar, f);
@@ -240,7 +255,7 @@ nir_color_mask(
static nir_ssa_def *
nir_logicop_func(
nir_builder *b,
unsigned func,
enum pipe_logicop func,
nir_ssa_def *src, nir_ssa_def *dst, nir_ssa_def *bitmask)
{
switch (func) {
@@ -440,12 +455,12 @@ nir_blend(
psrc = nir_blend_factor(
b, psrc,
src, src1, dst, bconst, c,
chan.src_factor, chan.invert_src_factor, format);
chan.src_factor, format);
pdst = nir_blend_factor(
b, pdst,
src, src1, dst, bconst, c,
chan.dst_factor, chan.invert_dst_factor, format);
chan.dst_factor, format);
}
channels[c] = nir_blend_func(b, chan.func, psrc, pdst);
@@ -473,9 +488,9 @@ color_index_for_location(unsigned location)
static bool
nir_blend_replace_channel(const nir_lower_blend_channel *c)
{
return (c->func == BLEND_FUNC_ADD) &&
(c->src_factor == BLEND_FACTOR_ZERO && c->invert_src_factor) &&
(c->dst_factor == BLEND_FACTOR_ZERO && !c->invert_dst_factor);
return (c->func == PIPE_BLEND_ADD) &&
(c->src_factor == PIPE_BLENDFACTOR_ONE) &&
(c->dst_factor == PIPE_BLENDFACTOR_ZERO);
}
static bool

View File

@@ -27,19 +27,16 @@
#include "compiler/nir/nir.h"
#include "util/format/u_formats.h"
#include "util/blend.h"
/* These structs encapsulates the blend state such that it can be lowered
* cleanly
*/
typedef struct {
enum blend_func func;
enum blend_factor src_factor;
bool invert_src_factor;
enum blend_factor dst_factor;
bool invert_dst_factor;
enum pipe_blend_func func;
enum pipe_blendfactor src_factor;
enum pipe_blendfactor dst_factor;
} nir_lower_blend_channel;
typedef struct {
@@ -55,7 +52,7 @@ typedef struct {
enum pipe_format format[8];
bool logicop_enable;
unsigned logicop_func;
enum pipe_logicop logicop_func;
/* If set, will use load_blend_const_color_{r,g,b,a}_float instead of
* load_blend_const_color_rgba */

View File

@@ -181,35 +181,21 @@ agx_create_blend_state(struct pipe_context *ctx,
/* No blending, but we get the colour mask below */
} else if (!rt.blend_enable) {
static const nir_lower_blend_channel replace = {
.func = BLEND_FUNC_ADD,
.src_factor = BLEND_FACTOR_ZERO,
.invert_src_factor = true,
.dst_factor = BLEND_FACTOR_ZERO,
.invert_dst_factor = false,
.func = PIPE_BLEND_ADD,
.src_factor = PIPE_BLENDFACTOR_ONE,
.dst_factor = PIPE_BLENDFACTOR_ZERO,
};
so->rt[i].rgb = replace;
so->rt[i].alpha = replace;
} else {
so->rt[i].rgb.func = util_blend_func_to_shader(rt.rgb_func);
so->rt[i].rgb.src_factor =
util_blend_factor_to_shader(rt.rgb_src_factor);
so->rt[i].rgb.invert_src_factor =
util_blend_factor_is_inverted(rt.rgb_src_factor);
so->rt[i].rgb.dst_factor =
util_blend_factor_to_shader(rt.rgb_dst_factor);
so->rt[i].rgb.invert_dst_factor =
util_blend_factor_is_inverted(rt.rgb_dst_factor);
so->rt[i].rgb.func = rt.rgb_func;
so->rt[i].rgb.src_factor = rt.rgb_src_factor;
so->rt[i].rgb.dst_factor = rt.rgb_dst_factor;
so->rt[i].alpha.func = util_blend_func_to_shader(rt.alpha_func);
so->rt[i].alpha.src_factor =
util_blend_factor_to_shader(rt.alpha_src_factor);
so->rt[i].alpha.invert_src_factor =
util_blend_factor_is_inverted(rt.alpha_src_factor);
so->rt[i].alpha.dst_factor =
util_blend_factor_to_shader(rt.alpha_dst_factor);
so->rt[i].alpha.invert_dst_factor =
util_blend_factor_is_inverted(rt.alpha_dst_factor);
so->rt[i].alpha.func = rt.alpha_func;
so->rt[i].alpha.src_factor = rt.alpha_src_factor;
so->rt[i].alpha.dst_factor = rt.alpha_dst_factor;
so->blend_enable = true;
}
@@ -1631,11 +1617,9 @@ agx_create_shader_state(struct pipe_context *pctx,
key.fs.blend.rt[i].colormask = 0xF;
const nir_lower_blend_channel replace = {
.func = BLEND_FUNC_ADD,
.src_factor = BLEND_FACTOR_ZERO,
.invert_src_factor = true,
.dst_factor = BLEND_FACTOR_ZERO,
.invert_dst_factor = false,
.func = PIPE_BLEND_ADD,
.src_factor = PIPE_BLENDFACTOR_ONE,
.dst_factor = PIPE_BLENDFACTOR_ZERO,
};
key.fs.blend.rt[i].rgb = replace;

View File

@@ -23,6 +23,7 @@
*/
#include "pan_blend.h"
#include "util/blend.h"
#ifdef PAN_ARCH
#include "pan_shader.h"
@@ -36,6 +37,67 @@
#include "util/format/u_format.h"
#include "pan_texture.h"
static inline enum pipe_blend_func
to_pipe_blend_func(enum blend_func func)
{
switch (func) {
case BLEND_FUNC_ADD:
return PIPE_BLEND_ADD;
case BLEND_FUNC_SUBTRACT:
return PIPE_BLEND_SUBTRACT;
case BLEND_FUNC_REVERSE_SUBTRACT:
return PIPE_BLEND_REVERSE_SUBTRACT;
case BLEND_FUNC_MIN:
return PIPE_BLEND_MIN;
case BLEND_FUNC_MAX:
return PIPE_BLEND_MAX;
}
unreachable("invalid");
}
static inline enum pipe_blendfactor
to_pipe_blendfactor_uninverted(enum blend_factor factor)
{
switch (factor) {
case BLEND_FACTOR_SRC_COLOR:
return PIPE_BLENDFACTOR_SRC_COLOR;
case BLEND_FACTOR_SRC1_COLOR:
return PIPE_BLENDFACTOR_SRC1_COLOR;
case BLEND_FACTOR_DST_COLOR:
return PIPE_BLENDFACTOR_DST_COLOR;
case BLEND_FACTOR_SRC_ALPHA:
return PIPE_BLENDFACTOR_SRC_ALPHA;
case BLEND_FACTOR_SRC1_ALPHA:
return PIPE_BLENDFACTOR_SRC1_ALPHA;
case BLEND_FACTOR_DST_ALPHA:
return PIPE_BLENDFACTOR_DST_ALPHA;
case BLEND_FACTOR_CONSTANT_COLOR:
return PIPE_BLENDFACTOR_CONST_COLOR;
case BLEND_FACTOR_CONSTANT_ALPHA:
return PIPE_BLENDFACTOR_CONST_ALPHA;
case BLEND_FACTOR_SRC_ALPHA_SATURATE:
return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE;
default:
unreachable("Invalid");
}
}
static inline enum pipe_blendfactor
to_pipe_blendfactor(enum blend_factor factor, bool inverted)
{
/* Flipped so handle special */
if (factor == BLEND_FACTOR_ZERO)
return inverted ? PIPE_BLENDFACTOR_ONE : PIPE_BLENDFACTOR_ZERO;
enum pipe_blendfactor pipe = to_pipe_blendfactor_uninverted(factor);
if (inverted)
pipe |= PIPE_BLENDFACTOR_INVERT_BIT;
return pipe;
}
#ifndef PAN_ARCH
/* Fixed function blending */
@@ -637,30 +699,29 @@ GENX(pan_blend_create_shader)(const struct panfrost_device *dev,
if (!rt_state->equation.blend_enable) {
static const nir_lower_blend_channel replace = {
.func = BLEND_FUNC_ADD,
.src_factor = BLEND_FACTOR_ZERO,
.invert_src_factor = true,
.dst_factor = BLEND_FACTOR_ZERO,
.invert_dst_factor = false,
.func = PIPE_BLEND_ADD,
.src_factor = PIPE_BLENDFACTOR_ONE,
.dst_factor = PIPE_BLENDFACTOR_ZERO,
};
options.rt[rt].rgb = replace;
options.rt[rt].alpha = replace;
} else {
options.rt[rt].rgb.func = rt_state->equation.rgb_func;
options.rt[rt].rgb.src_factor = rt_state->equation.rgb_src_factor;
options.rt[rt].rgb.invert_src_factor =
rt_state->equation.rgb_invert_src_factor;
options.rt[rt].rgb.dst_factor = rt_state->equation.rgb_dst_factor;
options.rt[rt].rgb.invert_dst_factor =
rt_state->equation.rgb_invert_dst_factor;
options.rt[rt].alpha.func = rt_state->equation.alpha_func;
options.rt[rt].alpha.src_factor = rt_state->equation.alpha_src_factor;
options.rt[rt].alpha.invert_src_factor =
rt_state->equation.alpha_invert_src_factor;
options.rt[rt].alpha.dst_factor = rt_state->equation.alpha_dst_factor;
options.rt[rt].alpha.invert_dst_factor =
rt_state->equation.alpha_invert_dst_factor;
options.rt[rt].rgb.func = to_pipe_blend_func(rt_state->equation.rgb_func);
options.rt[rt].rgb.src_factor =
to_pipe_blendfactor(rt_state->equation.rgb_src_factor,
rt_state->equation.rgb_invert_src_factor);
options.rt[rt].rgb.dst_factor =
to_pipe_blendfactor(rt_state->equation.rgb_dst_factor,
rt_state->equation.rgb_invert_dst_factor);
options.rt[rt].alpha.func =
to_pipe_blend_func(rt_state->equation.alpha_func);
options.rt[rt].alpha.src_factor =
to_pipe_blendfactor(rt_state->equation.alpha_src_factor,
rt_state->equation.alpha_invert_src_factor);
options.rt[rt].alpha.dst_factor =
to_pipe_blendfactor(rt_state->equation.alpha_dst_factor,
rt_state->equation.alpha_invert_dst_factor);
}
nir_ssa_def *pixel = nir_load_barycentric_pixel(&b, 32, .interp_mode = 1);

View File

@@ -120,6 +120,67 @@ panvk_lower_sysvals(nir_builder *b, nir_instr *instr, void *data)
return true;
}
static inline enum pipe_blend_func
to_pipe_blend_func(enum blend_func func)
{
switch (func) {
case BLEND_FUNC_ADD:
return PIPE_BLEND_ADD;
case BLEND_FUNC_SUBTRACT:
return PIPE_BLEND_SUBTRACT;
case BLEND_FUNC_REVERSE_SUBTRACT:
return PIPE_BLEND_REVERSE_SUBTRACT;
case BLEND_FUNC_MIN:
return PIPE_BLEND_MIN;
case BLEND_FUNC_MAX:
return PIPE_BLEND_MAX;
}
unreachable("invalid");
}
static inline enum pipe_blendfactor
to_pipe_blendfactor_uninverted(enum blend_factor factor)
{
switch (factor) {
case BLEND_FACTOR_SRC_COLOR:
return PIPE_BLENDFACTOR_SRC_COLOR;
case BLEND_FACTOR_SRC1_COLOR:
return PIPE_BLENDFACTOR_SRC1_COLOR;
case BLEND_FACTOR_DST_COLOR:
return PIPE_BLENDFACTOR_DST_COLOR;
case BLEND_FACTOR_SRC_ALPHA:
return PIPE_BLENDFACTOR_SRC_ALPHA;
case BLEND_FACTOR_SRC1_ALPHA:
return PIPE_BLENDFACTOR_SRC1_ALPHA;
case BLEND_FACTOR_DST_ALPHA:
return PIPE_BLENDFACTOR_DST_ALPHA;
case BLEND_FACTOR_CONSTANT_COLOR:
return PIPE_BLENDFACTOR_CONST_COLOR;
case BLEND_FACTOR_CONSTANT_ALPHA:
return PIPE_BLENDFACTOR_CONST_ALPHA;
case BLEND_FACTOR_SRC_ALPHA_SATURATE:
return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE;
default:
unreachable("Invalid");
}
}
static inline enum pipe_blendfactor
to_pipe_blendfactor(enum blend_factor factor, bool inverted)
{
/* Flipped so handle special */
if (factor == BLEND_FACTOR_ZERO)
return inverted ? PIPE_BLENDFACTOR_ONE : PIPE_BLENDFACTOR_ZERO;
enum pipe_blendfactor pipe = to_pipe_blendfactor_uninverted(factor);
if (inverted)
pipe |= PIPE_BLENDFACTOR_INVERT_BIT;
return pipe;
}
static void
panvk_lower_blend(struct panfrost_device *pdev, nir_shader *nir,
struct panfrost_compile_inputs *inputs,
@@ -145,30 +206,30 @@ panvk_lower_blend(struct panfrost_device *pdev, nir_shader *nir,
if (!rt_state->equation.blend_enable) {
static const nir_lower_blend_channel replace = {
.func = BLEND_FUNC_ADD,
.src_factor = BLEND_FACTOR_ZERO,
.invert_src_factor = true,
.dst_factor = BLEND_FACTOR_ZERO,
.invert_dst_factor = false,
.func = PIPE_BLEND_ADD,
.src_factor = PIPE_BLENDFACTOR_ONE,
.dst_factor = PIPE_BLENDFACTOR_ZERO,
};
options.rt[rt].rgb = replace;
options.rt[rt].alpha = replace;
} else {
options.rt[rt].rgb.func = rt_state->equation.rgb_func;
options.rt[rt].rgb.src_factor = rt_state->equation.rgb_src_factor;
options.rt[rt].rgb.invert_src_factor =
rt_state->equation.rgb_invert_src_factor;
options.rt[rt].rgb.dst_factor = rt_state->equation.rgb_dst_factor;
options.rt[rt].rgb.invert_dst_factor =
rt_state->equation.rgb_invert_dst_factor;
options.rt[rt].alpha.func = rt_state->equation.alpha_func;
options.rt[rt].alpha.src_factor = rt_state->equation.alpha_src_factor;
options.rt[rt].alpha.invert_src_factor =
rt_state->equation.alpha_invert_src_factor;
options.rt[rt].alpha.dst_factor = rt_state->equation.alpha_dst_factor;
options.rt[rt].alpha.invert_dst_factor =
rt_state->equation.alpha_invert_dst_factor;
options.rt[rt].rgb.func =
to_pipe_blend_func(rt_state->equation.rgb_func);
options.rt[rt].rgb.src_factor =
to_pipe_blendfactor(rt_state->equation.rgb_src_factor,
rt_state->equation.rgb_invert_src_factor);
options.rt[rt].rgb.dst_factor =
to_pipe_blendfactor(rt_state->equation.rgb_dst_factor,
rt_state->equation.rgb_invert_dst_factor);
options.rt[rt].alpha.func =
to_pipe_blend_func(rt_state->equation.alpha_func);
options.rt[rt].alpha.src_factor =
to_pipe_blendfactor(rt_state->equation.alpha_src_factor,
rt_state->equation.alpha_invert_src_factor);
options.rt[rt].alpha.dst_factor =
to_pipe_blendfactor(rt_state->equation.alpha_dst_factor,
rt_state->equation.alpha_invert_dst_factor);
}
/* Update the equation to force a color replacement */