From 91d9c55f3a435717224dace90b6181833ca9ea8e Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 12 Oct 2020 15:18:35 +0200 Subject: [PATCH] panfrost: Add blend shader support to bifrost Signed-off-by: Boris Brezillon Reviewed-by: Alyssa Rosenzweig Part-of: --- src/gallium/drivers/panfrost/pan_assemble.c | 8 +++ src/gallium/drivers/panfrost/pan_blend_shaders.c | 87 +++++++++++++++++++++++- src/gallium/drivers/panfrost/pan_cmdstream.c | 2 + src/gallium/drivers/panfrost/pan_context.h | 3 + 4 files changed, 99 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/panfrost/pan_assemble.c b/src/gallium/drivers/panfrost/pan_assemble.c index a7f2725..f2bc19d 100644 --- a/src/gallium/drivers/panfrost/pan_assemble.c +++ b/src/gallium/drivers/panfrost/pan_assemble.c @@ -298,6 +298,14 @@ panfrost_shader_compile(struct panfrost_context *ctx, break; case MESA_SHADER_FRAGMENT: + for (unsigned i = 0; i < ARRAY_SIZE(state->blend_ret_addrs); i++) { + if (!program.blend_ret_offsets[i]) + continue; + + state->blend_ret_addrs[i] = (state->bo->gpu & UINT32_MAX) + + program.blend_ret_offsets[i]; + assert(!(state->blend_ret_addrs[i] & 0x7)); + } varying_count = util_bitcount64(s->info.inputs_read); if (s->info.outputs_written & BITFIELD64_BIT(FRAG_RESULT_DEPTH)) state->writes_depth = true; diff --git a/src/gallium/drivers/panfrost/pan_blend_shaders.c b/src/gallium/drivers/panfrost/pan_blend_shaders.c index bdefdec..470f947 100644 --- a/src/gallium/drivers/panfrost/pan_blend_shaders.c +++ b/src/gallium/drivers/panfrost/pan_blend_shaders.c @@ -27,6 +27,7 @@ #include "pan_util.h" #include "panfrost-quirks.h" #include "midgard/midgard_compile.h" +#include "bifrost/bifrost_compile.h" #include "compiler/nir/nir_builder.h" #include "nir/nir_lower_blend.h" #include "panfrost/util/pan_lower_framebuffer.h" @@ -216,6 +217,84 @@ panfrost_create_blend_shader(struct panfrost_context *ctx, return res; } +static uint64_t +bifrost_get_blend_desc(enum pipe_format fmt, unsigned rt) +{ + const struct util_format_description *desc = util_format_description(fmt); + uint64_t res; + + pan_pack(&res, BIFROST_INTERNAL_BLEND, cfg) { + cfg.mode = MALI_BIFROST_BLEND_MODE_OPAQUE; + cfg.fixed_function.num_comps = desc->nr_channels; + cfg.fixed_function.rt = rt; + + nir_alu_type T = pan_unpacked_type_for_format(desc); + switch (T) { + case nir_type_float16: + cfg.fixed_function.conversion.register_format = + MALI_BIFROST_REGISTER_FILE_FORMAT_F16; + break; + case nir_type_float32: + cfg.fixed_function.conversion.register_format = + MALI_BIFROST_REGISTER_FILE_FORMAT_F32; + break; + case nir_type_int16: + cfg.fixed_function.conversion.register_format = + MALI_BIFROST_REGISTER_FILE_FORMAT_I16; + break; + case nir_type_int32: + cfg.fixed_function.conversion.register_format = + MALI_BIFROST_REGISTER_FILE_FORMAT_I32; + break; + case nir_type_uint16: + cfg.fixed_function.conversion.register_format = + MALI_BIFROST_REGISTER_FILE_FORMAT_U16; + break; + case nir_type_uint32: + cfg.fixed_function.conversion.register_format = + MALI_BIFROST_REGISTER_FILE_FORMAT_U32; + break; + default: + unreachable("Invalid format"); + } + + cfg.fixed_function.conversion.memory_format.srgb = + desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB; + + if (util_format_is_unorm8(desc)) { + cfg.fixed_function.conversion.memory_format.format = MALI_RGBA8_2; + continue; + } + + enum pipe_format linearized = util_format_linear(fmt); + switch (linearized) { + case PIPE_FORMAT_B5G6R5_UNORM: + cfg.fixed_function.conversion.memory_format.format = MALI_R5G6B5; + break; + case PIPE_FORMAT_A4B4G4R4_UNORM: + case PIPE_FORMAT_B4G4R4A4_UNORM: + case PIPE_FORMAT_R4G4B4A4_UNORM: + cfg.fixed_function.conversion.memory_format.format = MALI_RGBA4; + break; + case PIPE_FORMAT_R10G10B10A2_UNORM: + case PIPE_FORMAT_B10G10R10A2_UNORM: + case PIPE_FORMAT_R10G10B10X2_UNORM: + case PIPE_FORMAT_B10G10R10X2_UNORM: + cfg.fixed_function.conversion.memory_format.format = MALI_RGB10_A2_2; + break; + case PIPE_FORMAT_B5G5R5A1_UNORM: + case PIPE_FORMAT_R5G5B5A1_UNORM: + case PIPE_FORMAT_B5G5R5X1_UNORM: + cfg.fixed_function.conversion.memory_format.format = MALI_RGB5_A1; + break; + default: + unreachable("Invalid format"); + } + } + + return res; +} + void panfrost_compile_blend_shader(struct panfrost_blend_shader *shader, const float *constants) @@ -244,7 +323,13 @@ panfrost_compile_blend_shader(struct panfrost_blend_shader *shader, if (constants) memcpy(inputs.blend.constants, constants, sizeof(inputs.blend.constants)); - midgard_compile_shader_nir(shader->nir, &program, &inputs); + if (dev->quirks & IS_BIFROST) { + inputs.blend.bifrost_blend_desc = + bifrost_get_blend_desc(shader->key.format, shader->key.rt); + bifrost_compile_shader_nir(shader->nir, &program, &inputs); + } else { + midgard_compile_shader_nir(shader->nir, &program, &inputs); + } /* Allow us to patch later */ shader->first_tag = program.first_tag; diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index e481bbb..dd99e2c 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -297,6 +297,8 @@ panfrost_emit_bifrost_blend(struct panfrost_batch *batch, assert((blend[i].shader.gpu & (0xffffffffull << 32)) == (fs->bo->gpu & (0xffffffffull << 32))); cfg.bifrost.internal.shader.pc = (u32)blend[i].shader.gpu; + assert(!(fs->blend_ret_addrs[i] & 0x7)); + cfg.bifrost.internal.shader.return_value = fs->blend_ret_addrs[i]; cfg.bifrost.internal.mode = MALI_BIFROST_BLEND_MODE_SHADER; } else { enum pipe_format format = batch->key.cbufs[i]->format; diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index f725113..4452328 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -246,6 +246,9 @@ struct panfrost_shader_state { BITSET_WORD outputs_read; enum pipe_format rt_formats[8]; + + /* Blend return addresses */ + uint32_t blend_ret_addrs[8]; }; /* A collection of varyings (the CSO) */ -- 2.7.4