panfrost: Use common blend lowering
Contains a number of bugfixes. Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10601>
This commit is contained in:
parent
f3de2bd6c2
commit
e0419c29cc
|
@ -1,42 +1,18 @@
|
|||
dEQP-GLES31.functional.draw_base_vertex.draw_elements_base_vertex.builtin_variable.vertex_id,Fail
|
||||
dEQP-GLES31.functional.draw_base_vertex.draw_elements_instanced_base_vertex.builtin_variable.vertex_id,Fail
|
||||
dEQP-GLES31.functional.draw_base_vertex.draw_range_elements_base_vertex.builtin_variable.vertex_id,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.0,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.10,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.11,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.12,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.13,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.14,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.15,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.16,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.17,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.18,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.19,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.1,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.2,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.3,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.4,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.5,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.6,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.7,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.8,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.9,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.0,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.10,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.11,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.12,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.13,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.14,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.15,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.16,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.18,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.19,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.1,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.3,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.4,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.6,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.8,Fail
|
||||
dEQP-GLES31.functional.draw_buffers_indexed.random.max_required_draw_buffers.9,Fail
|
||||
dEQP-GLES31.functional.draw_indirect.draw_elements_indirect.line_strip.instanced_attributes,Fail
|
||||
dEQP-GLES31.functional.draw_indirect.random.31,Fail
|
||||
dEQP-GLES31.functional.layout_binding.image.image2d.vertex_binding_array,Fail
|
||||
|
|
|
@ -110,8 +110,6 @@ shared_FILES := \
|
|||
util_FILES := \
|
||||
util/lcra.c \
|
||||
util/lcra.h \
|
||||
util/nir_lower_blend.c \
|
||||
util/nir_lower_blend.h \
|
||||
util/nir_mod_helpers.c \
|
||||
util/pan_ir.c \
|
||||
util/pan_ir.h \
|
||||
|
|
|
@ -26,11 +26,11 @@
|
|||
#include "pan_shader.h"
|
||||
#include "pan_texture.h"
|
||||
#include "panfrost/util/pan_lower_framebuffer.h"
|
||||
#include "panfrost/util/nir_lower_blend.h"
|
||||
#include "util/format/u_format.h"
|
||||
#include "compiler/nir/nir.h"
|
||||
#include "compiler/nir/nir_builder.h"
|
||||
#include "compiler/nir/nir_conversion_builder.h"
|
||||
#include "compiler/nir/nir_lower_blend.h"
|
||||
|
||||
/* Fixed function blending */
|
||||
|
||||
|
@ -504,9 +504,8 @@ pan_blend_create_shader(const struct panfrost_device *dev,
|
|||
nir_lower_blend_options options = {
|
||||
.logicop_enable = state->logicop_enable,
|
||||
.logicop_func = state->logicop_func,
|
||||
.colormask = rt_state->equation.color_mask,
|
||||
.half = nir_type == nir_type_float16,
|
||||
.format = rt_state->format
|
||||
.rt[0].colormask = rt_state->equation.color_mask,
|
||||
.format[0] = rt_state->format
|
||||
};
|
||||
|
||||
if (!rt_state->equation.blend_enable) {
|
||||
|
@ -518,19 +517,19 @@ pan_blend_create_shader(const struct panfrost_device *dev,
|
|||
.invert_dst_factor = false,
|
||||
};
|
||||
|
||||
options.rgb = replace;
|
||||
options.alpha = replace;
|
||||
options.rt[0].rgb = replace;
|
||||
options.rt[0].alpha = replace;
|
||||
} else {
|
||||
options.rgb.func = rt_state->equation.rgb_func;
|
||||
options.rgb.src_factor = rt_state->equation.rgb_src_factor;
|
||||
options.rgb.invert_src_factor = rt_state->equation.rgb_invert_src_factor;
|
||||
options.rgb.dst_factor = rt_state->equation.rgb_dst_factor;
|
||||
options.rgb.invert_dst_factor = rt_state->equation.rgb_invert_dst_factor;
|
||||
options.alpha.func = rt_state->equation.alpha_func;
|
||||
options.alpha.src_factor = rt_state->equation.alpha_src_factor;
|
||||
options.alpha.invert_src_factor = rt_state->equation.alpha_invert_src_factor;
|
||||
options.alpha.dst_factor = rt_state->equation.alpha_dst_factor;
|
||||
options.alpha.invert_dst_factor = rt_state->equation.alpha_invert_dst_factor;
|
||||
options.rt[0].rgb.func = rt_state->equation.rgb_func;
|
||||
options.rt[0].rgb.src_factor = rt_state->equation.rgb_src_factor;
|
||||
options.rt[0].rgb.invert_src_factor = rt_state->equation.rgb_invert_src_factor;
|
||||
options.rt[0].rgb.dst_factor = rt_state->equation.rgb_dst_factor;
|
||||
options.rt[0].rgb.invert_dst_factor = rt_state->equation.rgb_invert_dst_factor;
|
||||
options.rt[0].alpha.func = rt_state->equation.alpha_func;
|
||||
options.rt[0].alpha.src_factor = rt_state->equation.alpha_src_factor;
|
||||
options.rt[0].alpha.invert_src_factor = rt_state->equation.alpha_invert_src_factor;
|
||||
options.rt[0].alpha.dst_factor = rt_state->equation.alpha_dst_factor;
|
||||
options.rt[0].alpha.invert_dst_factor = rt_state->equation.alpha_invert_dst_factor;
|
||||
}
|
||||
|
||||
nir_alu_type src_types[] = { src0_type ?: nir_type_float32, src1_type ?: nir_type_float32 };
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
libpanfrost_util_files = files(
|
||||
'lcra.c',
|
||||
'lcra.h',
|
||||
'nir_lower_blend.c',
|
||||
'nir_mod_helpers.c',
|
||||
'pan_ir.c',
|
||||
'pan_ir.h',
|
||||
|
|
|
@ -1,375 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Alyssa Rosenzweig
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Implements the fragment pipeline (blending and writeout) in software, to be
|
||||
* run as a dedicated "blend shader" stage on Midgard/Bifrost, or as a fragment
|
||||
* shader variant on typical GPUs. This pass is useful if hardware lacks
|
||||
* fixed-function blending in part or in full.
|
||||
*/
|
||||
|
||||
#include "compiler/nir/nir.h"
|
||||
#include "compiler/nir/nir_builder.h"
|
||||
#include "compiler/nir/nir_format_convert.h"
|
||||
#include "nir_lower_blend.h"
|
||||
|
||||
/* Given processed factors, combine them per a blend function */
|
||||
|
||||
static nir_ssa_def *
|
||||
nir_blend_func(
|
||||
nir_builder *b,
|
||||
enum blend_func func,
|
||||
nir_ssa_def *src, nir_ssa_def *dst)
|
||||
{
|
||||
switch (func) {
|
||||
case BLEND_FUNC_ADD:
|
||||
return nir_fadd(b, src, dst);
|
||||
case BLEND_FUNC_SUBTRACT:
|
||||
return nir_fsub(b, src, dst);
|
||||
case BLEND_FUNC_REVERSE_SUBTRACT:
|
||||
return nir_fsub(b, dst, src);
|
||||
case BLEND_FUNC_MIN:
|
||||
return nir_fmin(b, src, dst);
|
||||
case BLEND_FUNC_MAX:
|
||||
return nir_fmax(b, src, dst);
|
||||
}
|
||||
|
||||
unreachable("Invalid blend function");
|
||||
}
|
||||
|
||||
/* Does this blend function multiply by a blend factor? */
|
||||
|
||||
static bool
|
||||
nir_blend_factored(enum blend_func func)
|
||||
{
|
||||
switch (func) {
|
||||
case BLEND_FUNC_ADD:
|
||||
case BLEND_FUNC_SUBTRACT:
|
||||
case BLEND_FUNC_REVERSE_SUBTRACT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute a src_alpha_saturate factor */
|
||||
static nir_ssa_def *
|
||||
nir_alpha_saturate(
|
||||
nir_builder *b,
|
||||
nir_ssa_def *src, nir_ssa_def *dst,
|
||||
unsigned chan)
|
||||
{
|
||||
nir_ssa_def *Asrc = nir_channel(b, src, 3);
|
||||
nir_ssa_def *Adst = nir_channel(b, dst, 3);
|
||||
nir_ssa_def *one = nir_imm_floatN_t(b, 1.0, src->bit_size);
|
||||
nir_ssa_def *Adsti = nir_fsub(b, one, Adst);
|
||||
|
||||
return (chan < 3) ? nir_fmin(b, Asrc, Adsti) : one;
|
||||
}
|
||||
|
||||
/* Returns a scalar single factor, unmultiplied */
|
||||
|
||||
static nir_ssa_def *
|
||||
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)
|
||||
{
|
||||
switch (factor) {
|
||||
case BLEND_FACTOR_ZERO:
|
||||
return nir_imm_floatN_t(b, 0.0, src->bit_size);
|
||||
case BLEND_FACTOR_SRC_COLOR:
|
||||
return nir_channel(b, src, chan);
|
||||
case BLEND_FACTOR_SRC1_COLOR:
|
||||
return nir_channel(b, src1, chan);
|
||||
case BLEND_FACTOR_DST_COLOR:
|
||||
return nir_channel(b, dst, chan);
|
||||
case BLEND_FACTOR_SRC_ALPHA:
|
||||
return nir_channel(b, src, 3);
|
||||
case BLEND_FACTOR_SRC1_ALPHA:
|
||||
return nir_channel(b, src1, 3);
|
||||
case BLEND_FACTOR_DST_ALPHA:
|
||||
return nir_channel(b, dst, 3);
|
||||
case BLEND_FACTOR_CONSTANT_COLOR:
|
||||
return nir_channel(b, bconst, chan);
|
||||
case BLEND_FACTOR_CONSTANT_ALPHA:
|
||||
return nir_channel(b, bconst, 3);
|
||||
case BLEND_FACTOR_SRC_ALPHA_SATURATE:
|
||||
return nir_alpha_saturate(b, src, dst, chan);
|
||||
}
|
||||
|
||||
unreachable("Invalid blend factor");
|
||||
}
|
||||
|
||||
static nir_ssa_def *
|
||||
nir_blend_factor(
|
||||
nir_builder *b,
|
||||
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)
|
||||
{
|
||||
nir_ssa_def *f =
|
||||
nir_blend_factor_value(b, src, src1, dst, bconst, chan, factor);
|
||||
|
||||
if (inverted)
|
||||
f = nir_fadd_imm(b, nir_fneg(b, f), 1.0);
|
||||
|
||||
return nir_fmul(b, raw_scalar, f);
|
||||
}
|
||||
|
||||
/* Given a colormask, "blend" with the destination */
|
||||
|
||||
static nir_ssa_def *
|
||||
nir_color_mask(
|
||||
nir_builder *b,
|
||||
unsigned mask,
|
||||
nir_ssa_def *src,
|
||||
nir_ssa_def *dst)
|
||||
{
|
||||
nir_ssa_def *masked[4];
|
||||
|
||||
for (unsigned c = 0; c < 4; ++c) {
|
||||
bool enab = (mask & (1 << c));
|
||||
masked[c] = enab ? nir_channel(b, src, c) : nir_channel(b, dst, c);
|
||||
}
|
||||
|
||||
return nir_vec(b, masked, 4);
|
||||
}
|
||||
|
||||
static nir_ssa_def *
|
||||
nir_logicop_func(
|
||||
nir_builder *b,
|
||||
unsigned func,
|
||||
nir_ssa_def *src, nir_ssa_def *dst)
|
||||
{
|
||||
switch (func) {
|
||||
case PIPE_LOGICOP_CLEAR:
|
||||
return nir_imm_ivec4(b, 0, 0, 0, 0);
|
||||
case PIPE_LOGICOP_NOR:
|
||||
return nir_inot(b, nir_ior(b, src, dst));
|
||||
case PIPE_LOGICOP_AND_INVERTED:
|
||||
return nir_iand(b, nir_inot(b, src), dst);
|
||||
case PIPE_LOGICOP_COPY_INVERTED:
|
||||
return nir_inot(b, src);
|
||||
case PIPE_LOGICOP_AND_REVERSE:
|
||||
return nir_iand(b, src, nir_inot(b, dst));
|
||||
case PIPE_LOGICOP_INVERT:
|
||||
return nir_inot(b, dst);
|
||||
case PIPE_LOGICOP_XOR:
|
||||
return nir_ixor(b, src, dst);
|
||||
case PIPE_LOGICOP_NAND:
|
||||
return nir_inot(b, nir_iand(b, src, dst));
|
||||
case PIPE_LOGICOP_AND:
|
||||
return nir_iand(b, src, dst);
|
||||
case PIPE_LOGICOP_EQUIV:
|
||||
return nir_inot(b, nir_ixor(b, src, dst));
|
||||
case PIPE_LOGICOP_NOOP:
|
||||
return dst;
|
||||
case PIPE_LOGICOP_OR_INVERTED:
|
||||
return nir_ior(b, nir_inot(b, src), dst);
|
||||
case PIPE_LOGICOP_COPY:
|
||||
return src;
|
||||
case PIPE_LOGICOP_OR_REVERSE:
|
||||
return nir_ior(b, src, nir_inot(b, dst));
|
||||
case PIPE_LOGICOP_OR:
|
||||
return nir_ior(b, src, dst);
|
||||
case PIPE_LOGICOP_SET:
|
||||
return nir_imm_ivec4(b, ~0, ~0, ~0, ~0);
|
||||
}
|
||||
|
||||
unreachable("Invalid logciop function");
|
||||
}
|
||||
|
||||
static nir_ssa_def *
|
||||
nir_blend_logicop(
|
||||
nir_builder *b,
|
||||
nir_lower_blend_options options,
|
||||
nir_ssa_def *src, nir_ssa_def *dst)
|
||||
{
|
||||
const struct util_format_description *format_desc =
|
||||
util_format_description(options.format);
|
||||
|
||||
if (options.half) {
|
||||
src = nir_f2f32(b, src);
|
||||
dst = nir_f2f32(b, dst);
|
||||
}
|
||||
|
||||
assert(src->num_components <= 4);
|
||||
assert(dst->num_components <= 4);
|
||||
|
||||
unsigned bits[4];
|
||||
for (int i = 0; i < 4; ++i)
|
||||
bits[i] = format_desc->channel[i].size;
|
||||
|
||||
src = nir_format_float_to_unorm(b, src, bits);
|
||||
dst = nir_format_float_to_unorm(b, dst, bits);
|
||||
|
||||
nir_ssa_def *out = nir_logicop_func(b, options.logicop_func, src, dst);
|
||||
|
||||
if (bits[0] < 32) {
|
||||
nir_const_value mask[4];
|
||||
for (int i = 0; i < 4; ++i)
|
||||
mask[i] = nir_const_value_for_int((1u << bits[i]) - 1, 32);
|
||||
|
||||
out = nir_iand(b, out, nir_build_imm(b, 4, 32, mask));
|
||||
}
|
||||
|
||||
out = nir_format_unorm_to_float(b, out, bits);
|
||||
|
||||
if (options.half)
|
||||
out = nir_f2f16(b, out);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Given a blend state, the source color, and the destination color,
|
||||
* return the blended color
|
||||
*/
|
||||
|
||||
static nir_ssa_def *
|
||||
nir_blend(
|
||||
nir_builder *b,
|
||||
nir_lower_blend_options options,
|
||||
nir_ssa_def *src, nir_ssa_def *src1, nir_ssa_def *dst)
|
||||
{
|
||||
if (options.logicop_enable)
|
||||
return nir_blend_logicop(b, options, src, dst);
|
||||
|
||||
/* Grab the blend constant ahead of time */
|
||||
nir_ssa_def *bconst;
|
||||
if (options.scalar) {
|
||||
bconst = nir_vec4(b,
|
||||
nir_load_blend_const_color_r_float(b),
|
||||
nir_load_blend_const_color_g_float(b),
|
||||
nir_load_blend_const_color_b_float(b),
|
||||
nir_load_blend_const_color_a_float(b));
|
||||
} else {
|
||||
bconst = nir_load_blend_const_color_rgba(b);
|
||||
}
|
||||
|
||||
if (options.half)
|
||||
bconst = nir_f2f16(b, bconst);
|
||||
|
||||
/* We blend per channel and recombine later */
|
||||
nir_ssa_def *channels[4];
|
||||
|
||||
for (unsigned c = 0; c < 4; ++c) {
|
||||
/* Decide properties based on channel */
|
||||
nir_lower_blend_channel chan =
|
||||
(c < 3) ? options.rgb : options.alpha;
|
||||
|
||||
nir_ssa_def *psrc = nir_channel(b, src, c);
|
||||
nir_ssa_def *pdst = nir_channel(b, dst, c);
|
||||
|
||||
if (nir_blend_factored(chan.func)) {
|
||||
psrc = nir_blend_factor(
|
||||
b, psrc,
|
||||
src, src1, dst, bconst, c,
|
||||
chan.src_factor, chan.invert_src_factor);
|
||||
|
||||
pdst = nir_blend_factor(
|
||||
b, pdst,
|
||||
src, src1, dst, bconst, c,
|
||||
chan.dst_factor, chan.invert_dst_factor);
|
||||
}
|
||||
|
||||
channels[c] = nir_blend_func(b, chan.func, psrc, pdst);
|
||||
}
|
||||
|
||||
/* Then just recombine with an applied colormask */
|
||||
nir_ssa_def *blended = nir_vec(b, channels, 4);
|
||||
return nir_color_mask(b, options.colormask, blended, dst);
|
||||
}
|
||||
|
||||
static bool
|
||||
nir_is_blend_channel_replace(nir_lower_blend_channel chan)
|
||||
{
|
||||
return
|
||||
(chan.src_factor == BLEND_FACTOR_ZERO) &&
|
||||
(chan.dst_factor == BLEND_FACTOR_ZERO) &&
|
||||
(chan.invert_src_factor && !chan.invert_dst_factor) &&
|
||||
(chan.func == BLEND_FUNC_ADD || chan.func == BLEND_FUNC_SUBTRACT || chan.func == BLEND_FUNC_MAX);
|
||||
}
|
||||
|
||||
static bool
|
||||
nir_is_blend_replace(nir_lower_blend_options options)
|
||||
{
|
||||
return
|
||||
nir_is_blend_channel_replace(options.rgb) &&
|
||||
nir_is_blend_channel_replace(options.alpha);
|
||||
}
|
||||
|
||||
static bool
|
||||
nir_lower_blend_instr(nir_builder *b, nir_instr *instr, void *data)
|
||||
{
|
||||
nir_lower_blend_options *options = data;
|
||||
if (instr->type != nir_instr_type_intrinsic)
|
||||
return false;
|
||||
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
if (intr->intrinsic != nir_intrinsic_store_deref)
|
||||
return false;
|
||||
|
||||
/* TODO: Extending to MRT */
|
||||
nir_variable *var = nir_intrinsic_get_var(intr, 0);
|
||||
if (var->data.location != FRAG_RESULT_COLOR &&
|
||||
var->data.location < FRAG_RESULT_DATA0)
|
||||
return false;
|
||||
|
||||
b->cursor = nir_before_instr(instr);
|
||||
|
||||
/* Grab the input color */
|
||||
nir_ssa_def *src = nir_ssa_for_src(b, intr->src[1], 4);
|
||||
|
||||
/* Grab the dual-source input color */
|
||||
nir_ssa_def *src1 = options->src1;
|
||||
|
||||
/* Grab the tilebuffer color - io lowered to load_output */
|
||||
nir_ssa_def *dst = nir_load_var(b, var);
|
||||
|
||||
/* Blend the two colors per the passed options */
|
||||
nir_ssa_def *blended = nir_blend(b, *options, src, src1, dst);
|
||||
|
||||
/* Write out the final color instead of the input */
|
||||
nir_instr_rewrite_src_ssa(instr, &intr->src[1], blended);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nir_lower_blend(nir_shader *shader, nir_lower_blend_options options)
|
||||
{
|
||||
assert(shader->info.stage == MESA_SHADER_FRAGMENT);
|
||||
|
||||
/* Only run for actual blending, since there's nothing to do and we don't
|
||||
* want to degrade intermediate precision for non-blendable R32F targets) */
|
||||
|
||||
if (!nir_is_blend_replace(options)) {
|
||||
nir_shader_instructions_pass(shader, nir_lower_blend_instr,
|
||||
nir_metadata_block_index | nir_metadata_dominance, &options);
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Copyright  2019 Alyssa Rosenzweig
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NIR_BLEND_H
|
||||
#define NIR_BLEND_H
|
||||
|
||||
#include "compiler/nir/nir.h"
|
||||
#include "pipe/p_format.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;
|
||||
} nir_lower_blend_channel;
|
||||
|
||||
typedef struct {
|
||||
nir_lower_blend_channel rgb;
|
||||
nir_lower_blend_channel alpha;
|
||||
|
||||
/* 4-bit colormask. 0x0 for none, 0xF for RGBA, 0x1 for R */
|
||||
unsigned colormask;
|
||||
|
||||
bool logicop_enable;
|
||||
unsigned logicop_func;
|
||||
enum pipe_format format;
|
||||
|
||||
/* Use fp16 instead of fp32 */
|
||||
bool half;
|
||||
|
||||
bool scalar;
|
||||
nir_ssa_def *src1;
|
||||
} nir_lower_blend_options;
|
||||
|
||||
void nir_lower_blend(nir_shader *shader, nir_lower_blend_options options);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue