panfrost: Dual source blend support
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5620>
This commit is contained in:
@@ -99,7 +99,7 @@ GL 3.2, GLSL 1.50 --- all DONE: i965, nv50, nvc0, r600, radeonsi, llvmpipe, soft
|
|||||||
|
|
||||||
GL 3.3, GLSL 3.30 --- all DONE: i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe, virgl
|
GL 3.3, GLSL 3.30 --- all DONE: i965, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe, virgl
|
||||||
|
|
||||||
GL_ARB_blend_func_extended DONE (freedreno/a3xx, swr, zink)
|
GL_ARB_blend_func_extended DONE (freedreno/a3xx, swr, zink, panfrost)
|
||||||
GL_ARB_explicit_attrib_location DONE (all drivers that support GLSL)
|
GL_ARB_explicit_attrib_location DONE (all drivers that support GLSL)
|
||||||
GL_ARB_occlusion_query2 DONE (freedreno, swr, v3d, zink, panfrost)
|
GL_ARB_occlusion_query2 DONE (freedreno, swr, v3d, zink, panfrost)
|
||||||
GL_ARB_sampler_objects DONE (all drivers)
|
GL_ARB_sampler_objects DONE (all drivers)
|
||||||
|
@@ -95,7 +95,7 @@ nir_alpha_saturate(
|
|||||||
static nir_ssa_def *
|
static nir_ssa_def *
|
||||||
nir_blend_factor_value(
|
nir_blend_factor_value(
|
||||||
nir_builder *b,
|
nir_builder *b,
|
||||||
nir_ssa_def *src, nir_ssa_def *dst, nir_ssa_def *bconst,
|
nir_ssa_def *src, nir_ssa_def *src1, nir_ssa_def *dst, nir_ssa_def *bconst,
|
||||||
unsigned chan,
|
unsigned chan,
|
||||||
enum blend_factor factor,
|
enum blend_factor factor,
|
||||||
bool half)
|
bool half)
|
||||||
@@ -105,10 +105,14 @@ nir_blend_factor_value(
|
|||||||
return half ? nir_imm_float16(b, 0.0) : nir_imm_float(b, 0.0);
|
return half ? nir_imm_float16(b, 0.0) : nir_imm_float(b, 0.0);
|
||||||
case BLEND_FACTOR_SRC_COLOR:
|
case BLEND_FACTOR_SRC_COLOR:
|
||||||
return nir_channel(b, src, chan);
|
return nir_channel(b, src, chan);
|
||||||
|
case BLEND_FACTOR_SRC1_COLOR:
|
||||||
|
return nir_channel(b, src1, chan);
|
||||||
case BLEND_FACTOR_DST_COLOR:
|
case BLEND_FACTOR_DST_COLOR:
|
||||||
return nir_channel(b, dst, chan);
|
return nir_channel(b, dst, chan);
|
||||||
case BLEND_FACTOR_SRC_ALPHA:
|
case BLEND_FACTOR_SRC_ALPHA:
|
||||||
return nir_channel(b, src, 3);
|
return nir_channel(b, src, 3);
|
||||||
|
case BLEND_FACTOR_SRC1_ALPHA:
|
||||||
|
return nir_channel(b, src1, 3);
|
||||||
case BLEND_FACTOR_DST_ALPHA:
|
case BLEND_FACTOR_DST_ALPHA:
|
||||||
return nir_channel(b, dst, 3);
|
return nir_channel(b, dst, 3);
|
||||||
case BLEND_FACTOR_CONSTANT_COLOR:
|
case BLEND_FACTOR_CONSTANT_COLOR:
|
||||||
@@ -126,14 +130,14 @@ static nir_ssa_def *
|
|||||||
nir_blend_factor(
|
nir_blend_factor(
|
||||||
nir_builder *b,
|
nir_builder *b,
|
||||||
nir_ssa_def *raw_scalar,
|
nir_ssa_def *raw_scalar,
|
||||||
nir_ssa_def *src, nir_ssa_def *dst, nir_ssa_def *bconst,
|
nir_ssa_def *src, nir_ssa_def *src1, nir_ssa_def *dst, nir_ssa_def *bconst,
|
||||||
unsigned chan,
|
unsigned chan,
|
||||||
enum blend_factor factor,
|
enum blend_factor factor,
|
||||||
bool inverted,
|
bool inverted,
|
||||||
bool half)
|
bool half)
|
||||||
{
|
{
|
||||||
nir_ssa_def *f =
|
nir_ssa_def *f =
|
||||||
nir_blend_factor_value(b, src, dst, bconst, chan, factor, half);
|
nir_blend_factor_value(b, src, src1, dst, bconst, chan, factor, half);
|
||||||
|
|
||||||
nir_ssa_def *unity = half ? nir_imm_float16(b, 1.0) : nir_imm_float(b, 1.0);
|
nir_ssa_def *unity = half ? nir_imm_float16(b, 1.0) : nir_imm_float(b, 1.0);
|
||||||
|
|
||||||
@@ -256,7 +260,7 @@ static nir_ssa_def *
|
|||||||
nir_blend(
|
nir_blend(
|
||||||
nir_builder *b,
|
nir_builder *b,
|
||||||
nir_lower_blend_options options,
|
nir_lower_blend_options options,
|
||||||
nir_ssa_def *src, nir_ssa_def *dst)
|
nir_ssa_def *src, nir_ssa_def *src1, nir_ssa_def *dst)
|
||||||
{
|
{
|
||||||
if (options.logicop_enable)
|
if (options.logicop_enable)
|
||||||
return nir_blend_logicop(b, options, src, dst);
|
return nir_blend_logicop(b, options, src, dst);
|
||||||
@@ -281,12 +285,12 @@ nir_blend(
|
|||||||
if (nir_blend_factored(chan.func)) {
|
if (nir_blend_factored(chan.func)) {
|
||||||
psrc = nir_blend_factor(
|
psrc = nir_blend_factor(
|
||||||
b, psrc,
|
b, psrc,
|
||||||
src, dst, bconst, c,
|
src, src1, dst, bconst, c,
|
||||||
chan.src_factor, chan.invert_src_factor, options.half);
|
chan.src_factor, chan.invert_src_factor, options.half);
|
||||||
|
|
||||||
pdst = nir_blend_factor(
|
pdst = nir_blend_factor(
|
||||||
b, pdst,
|
b, pdst,
|
||||||
src, dst, bconst, c,
|
src, src1, dst, bconst, c,
|
||||||
chan.dst_factor, chan.invert_dst_factor, options.half);
|
chan.dst_factor, chan.invert_dst_factor, options.half);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,11 +353,14 @@ nir_lower_blend(nir_shader *shader, nir_lower_blend_options options)
|
|||||||
/* Grab the input color */
|
/* Grab the input color */
|
||||||
nir_ssa_def *src = nir_ssa_for_src(&b, intr->src[1], 4);
|
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 */
|
/* Grab the tilebuffer color - io lowered to load_output */
|
||||||
nir_ssa_def *dst = nir_load_var(&b, var);
|
nir_ssa_def *dst = nir_load_var(&b, var);
|
||||||
|
|
||||||
/* Blend the two colors per the passed options */
|
/* Blend the two colors per the passed options */
|
||||||
nir_ssa_def *blended = nir_blend(&b, options, src, dst);
|
nir_ssa_def *blended = nir_blend(&b, options, src, src1, dst);
|
||||||
|
|
||||||
/* Write out the final color instead of the input */
|
/* Write out the final color instead of the input */
|
||||||
nir_instr_rewrite_src(instr, &intr->src[1],
|
nir_instr_rewrite_src(instr, &intr->src[1],
|
||||||
|
@@ -55,6 +55,8 @@ typedef struct {
|
|||||||
|
|
||||||
/* Use fp16 instead of fp32 */
|
/* Use fp16 instead of fp32 */
|
||||||
bool half;
|
bool half;
|
||||||
|
|
||||||
|
nir_ssa_def *src1;
|
||||||
} nir_lower_blend_options;
|
} nir_lower_blend_options;
|
||||||
|
|
||||||
void nir_lower_blend(nir_shader *shader, nir_lower_blend_options options);
|
void nir_lower_blend(nir_shader *shader, nir_lower_blend_options options);
|
||||||
|
@@ -165,11 +165,15 @@ panfrost_compile_blend_shader(
|
|||||||
/* Create the blend variables */
|
/* Create the blend variables */
|
||||||
|
|
||||||
nir_variable *c_src = nir_variable_create(shader, nir_var_shader_in, glsl_vector_type(GLSL_TYPE_FLOAT, 4), "gl_Color");
|
nir_variable *c_src = nir_variable_create(shader, nir_var_shader_in, glsl_vector_type(GLSL_TYPE_FLOAT, 4), "gl_Color");
|
||||||
|
nir_variable *c_src1 = nir_variable_create(shader, nir_var_shader_in, glsl_vector_type(GLSL_TYPE_FLOAT, 4), "gl_Color1");
|
||||||
nir_variable *c_out = nir_variable_create(shader, nir_var_shader_out, glsl_vector_type(g, 4), "gl_FragColor");
|
nir_variable *c_out = nir_variable_create(shader, nir_var_shader_out, glsl_vector_type(g, 4), "gl_FragColor");
|
||||||
|
|
||||||
c_src->data.location = VARYING_SLOT_COL0;
|
c_src->data.location = VARYING_SLOT_COL0;
|
||||||
|
c_src1->data.location = VARYING_SLOT_VAR0;
|
||||||
c_out->data.location = FRAG_RESULT_COLOR;
|
c_out->data.location = FRAG_RESULT_COLOR;
|
||||||
|
|
||||||
|
c_src1->data.driver_location = 1;
|
||||||
|
|
||||||
/* Setup nir_builder */
|
/* Setup nir_builder */
|
||||||
|
|
||||||
nir_builder _b;
|
nir_builder _b;
|
||||||
@@ -179,25 +183,28 @@ panfrost_compile_blend_shader(
|
|||||||
|
|
||||||
/* Setup inputs */
|
/* Setup inputs */
|
||||||
|
|
||||||
nir_ssa_def *s_src = nir_load_var(b, c_src);
|
nir_ssa_def *s_src[] = {nir_load_var(b, c_src), nir_load_var(b, c_src1)};
|
||||||
|
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(s_src); ++i) {
|
||||||
if (T == nir_type_float16)
|
if (T == nir_type_float16)
|
||||||
s_src = nir_f2f16(b, s_src);
|
s_src[i] = nir_f2f16(b, s_src[i]);
|
||||||
else if (T == nir_type_int16)
|
else if (T == nir_type_int16)
|
||||||
s_src = nir_i2i16(b, nir_iclamp(b, s_src, -32768, 32767));
|
s_src[i] = nir_i2i16(b, nir_iclamp(b, s_src[i], -32768, 32767));
|
||||||
else if (T == nir_type_uint16)
|
else if (T == nir_type_uint16)
|
||||||
s_src = nir_u2u16(b, nir_umin(b, s_src, nir_imm_int(b, 65535)));
|
s_src[i] = nir_u2u16(b, nir_umin(b, s_src[i], nir_imm_int(b, 65535)));
|
||||||
else if (T == nir_type_int8)
|
else if (T == nir_type_int8)
|
||||||
s_src = nir_i2i8(b, nir_iclamp(b, s_src, -128, 127));
|
s_src[i] = nir_i2i8(b, nir_iclamp(b, s_src[i], -128, 127));
|
||||||
else if (T == nir_type_uint8)
|
else if (T == nir_type_uint8)
|
||||||
s_src = nir_u2u8(b, nir_umin(b, s_src, nir_imm_int(b, 255)));
|
s_src[i] = nir_u2u8(b, nir_umin(b, s_src[i], nir_imm_int(b, 255)));
|
||||||
|
}
|
||||||
|
|
||||||
/* Build a trivial blend shader */
|
/* Build a trivial blend shader */
|
||||||
nir_store_var(b, c_out, s_src, 0xFF);
|
nir_store_var(b, c_out, s_src[0], 0xFF);
|
||||||
|
|
||||||
nir_lower_blend_options options =
|
nir_lower_blend_options options =
|
||||||
nir_make_options(cso, rt);
|
nir_make_options(cso, rt);
|
||||||
options.format = format;
|
options.format = format;
|
||||||
|
options.src1 = s_src[1];
|
||||||
|
|
||||||
if (T == nir_type_float16)
|
if (T == nir_type_float16)
|
||||||
options.half = true;
|
options.half = true;
|
||||||
|
@@ -120,7 +120,7 @@ panfrost_get_param(struct pipe_screen *screen, enum pipe_cap param)
|
|||||||
return is_gles3 ? 4 : 1;
|
return is_gles3 ? 4 : 1;
|
||||||
|
|
||||||
case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
|
case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
|
||||||
return is_gl3 ? 1 : 0;
|
return 1;
|
||||||
|
|
||||||
/* Throttling frames breaks pipelining */
|
/* Throttling frames breaks pipelining */
|
||||||
case PIPE_CAP_THROTTLE:
|
case PIPE_CAP_THROTTLE:
|
||||||
|
Reference in New Issue
Block a user