From 787c1ed2096af39a98893e779f49bacf5efdcee2 Mon Sep 17 00:00:00 2001 From: Icecream95 Date: Thu, 25 Jun 2020 22:56:14 +1200 Subject: [PATCH] panfrost: Dual source blend support Reviewed-by: Alyssa Rosenzweig Part-of: --- docs/features.txt | 2 +- .../drivers/panfrost/nir/nir_lower_blend.c | 21 ++++++++---- .../drivers/panfrost/nir/nir_lower_blend.h | 2 ++ .../drivers/panfrost/pan_blend_shaders.c | 33 +++++++++++-------- src/gallium/drivers/panfrost/pan_screen.c | 2 +- 5 files changed, 38 insertions(+), 22 deletions(-) diff --git a/docs/features.txt b/docs/features.txt index 9af96985be6..e147967d420 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -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_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_occlusion_query2 DONE (freedreno, swr, v3d, zink, panfrost) GL_ARB_sampler_objects DONE (all drivers) diff --git a/src/gallium/drivers/panfrost/nir/nir_lower_blend.c b/src/gallium/drivers/panfrost/nir/nir_lower_blend.c index 13cef5d6e14..a325a77fa87 100644 --- a/src/gallium/drivers/panfrost/nir/nir_lower_blend.c +++ b/src/gallium/drivers/panfrost/nir/nir_lower_blend.c @@ -95,7 +95,7 @@ nir_alpha_saturate( static nir_ssa_def * nir_blend_factor_value( 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, enum blend_factor factor, bool half) @@ -105,10 +105,14 @@ nir_blend_factor_value( return half ? nir_imm_float16(b, 0.0) : nir_imm_float(b, 0.0); 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: @@ -126,14 +130,14 @@ static nir_ssa_def * nir_blend_factor( nir_builder *b, 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, enum blend_factor factor, bool inverted, bool half) { 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); @@ -256,7 +260,7 @@ static nir_ssa_def * nir_blend( nir_builder *b, 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) return nir_blend_logicop(b, options, src, dst); @@ -281,12 +285,12 @@ nir_blend( if (nir_blend_factored(chan.func)) { psrc = nir_blend_factor( b, psrc, - src, dst, bconst, c, + src, src1, dst, bconst, c, chan.src_factor, chan.invert_src_factor, options.half); pdst = nir_blend_factor( b, pdst, - src, dst, bconst, c, + src, src1, dst, bconst, c, 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 */ 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, dst); + nir_ssa_def *blended = nir_blend(&b, options, src, src1, dst); /* Write out the final color instead of the input */ nir_instr_rewrite_src(instr, &intr->src[1], diff --git a/src/gallium/drivers/panfrost/nir/nir_lower_blend.h b/src/gallium/drivers/panfrost/nir/nir_lower_blend.h index 4bce2cc79b8..f015bba1473 100644 --- a/src/gallium/drivers/panfrost/nir/nir_lower_blend.h +++ b/src/gallium/drivers/panfrost/nir/nir_lower_blend.h @@ -55,6 +55,8 @@ typedef struct { /* Use fp16 instead of fp32 */ bool half; + + nir_ssa_def *src1; } nir_lower_blend_options; void nir_lower_blend(nir_shader *shader, nir_lower_blend_options options); diff --git a/src/gallium/drivers/panfrost/pan_blend_shaders.c b/src/gallium/drivers/panfrost/pan_blend_shaders.c index 32132e22ecd..74aac4ebb38 100644 --- a/src/gallium/drivers/panfrost/pan_blend_shaders.c +++ b/src/gallium/drivers/panfrost/pan_blend_shaders.c @@ -165,11 +165,15 @@ panfrost_compile_blend_shader( /* 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_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"); c_src->data.location = VARYING_SLOT_COL0; + c_src1->data.location = VARYING_SLOT_VAR0; c_out->data.location = FRAG_RESULT_COLOR; + c_src1->data.driver_location = 1; + /* Setup nir_builder */ nir_builder _b; @@ -179,25 +183,28 @@ panfrost_compile_blend_shader( /* Setup inputs */ - nir_ssa_def *s_src = nir_load_var(b, c_src); - - if (T == nir_type_float16) - s_src = nir_f2f16(b, s_src); - else if (T == nir_type_int16) - s_src = nir_i2i16(b, nir_iclamp(b, s_src, -32768, 32767)); - else if (T == nir_type_uint16) - s_src = nir_u2u16(b, nir_umin(b, s_src, nir_imm_int(b, 65535))); - else if (T == nir_type_int8) - s_src = nir_i2i8(b, nir_iclamp(b, s_src, -128, 127)); - else if (T == nir_type_uint8) - s_src = nir_u2u8(b, nir_umin(b, s_src, nir_imm_int(b, 255))); + 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) + s_src[i] = nir_f2f16(b, s_src[i]); + else if (T == nir_type_int16) + s_src[i] = nir_i2i16(b, nir_iclamp(b, s_src[i], -32768, 32767)); + else if (T == nir_type_uint16) + s_src[i] = nir_u2u16(b, nir_umin(b, s_src[i], nir_imm_int(b, 65535))); + else if (T == nir_type_int8) + s_src[i] = nir_i2i8(b, nir_iclamp(b, s_src[i], -128, 127)); + else if (T == nir_type_uint8) + s_src[i] = nir_u2u8(b, nir_umin(b, s_src[i], nir_imm_int(b, 255))); + } /* 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_make_options(cso, rt); options.format = format; + options.src1 = s_src[1]; if (T == nir_type_float16) options.half = true; diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c index 1cb7fc3cbda..e22363ff533 100644 --- a/src/gallium/drivers/panfrost/pan_screen.c +++ b/src/gallium/drivers/panfrost/pan_screen.c @@ -120,7 +120,7 @@ panfrost_get_param(struct pipe_screen *screen, enum pipe_cap param) return is_gles3 ? 4 : 1; case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: - return is_gl3 ? 1 : 0; + return 1; /* Throttling frames breaks pipelining */ case PIPE_CAP_THROTTLE: -- 2.30.2