aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorTomeu Vizoso <[email protected]>2020-04-24 08:40:51 +0200
committerTomeu Vizoso <[email protected]>2020-04-30 16:27:34 +0200
commit3c98c452f012d20bcca3038af88bcbe7278d9c68 (patch)
tree1ff26ab78a81cf1a524c224fd1950ffe1be53a0d /src/gallium
parent33b13b9fbd2998977f76bfeeacf63900b0ed9cba (diff)
panfrost: Emit blend descriptors on Bifrost
Signed-off-by: Tomeu Vizoso <[email protected]> Reviewed-by: Alyssa Rosenzweig <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4724>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/panfrost/pan_assemble.c29
-rw-r--r--src/gallium/drivers/panfrost/pan_cmdstream.c87
-rw-r--r--src/gallium/drivers/panfrost/pan_context.h2
3 files changed, 97 insertions, 21 deletions
diff --git a/src/gallium/drivers/panfrost/pan_assemble.c b/src/gallium/drivers/panfrost/pan_assemble.c
index 4f8e14b105e..4c047c76a84 100644
--- a/src/gallium/drivers/panfrost/pan_assemble.c
+++ b/src/gallium/drivers/panfrost/pan_assemble.c
@@ -90,6 +90,31 @@ pan_format_from_glsl(const struct glsl_type *type)
MALI_NR_CHANNELS(4);
}
+static enum bifrost_shader_type
+bifrost_blend_type_from_nir(nir_alu_type nir_type)
+{
+ switch(nir_type) {
+ case 0: /* Render target not in use */
+ return 0;
+ case nir_type_float16:
+ return BIFROST_BLEND_F16;
+ case nir_type_float32:
+ return BIFROST_BLEND_F32;
+ case nir_type_int32:
+ return BIFROST_BLEND_I32;
+ case nir_type_uint32:
+ return BIFROST_BLEND_U32;
+ case nir_type_int16:
+ return BIFROST_BLEND_I16;
+ case nir_type_uint16:
+ return BIFROST_BLEND_U16;
+ default:
+ DBG("Unsupported blend shader type for NIR alu type %d", nir_type);
+ assert(0);
+ return 0;
+ }
+}
+
void
panfrost_shader_compile(struct panfrost_context *ctx,
enum pipe_shader_ir ir_type,
@@ -197,6 +222,10 @@ panfrost_shader_compile(struct panfrost_context *ctx,
state->uniform_cutoff = program.uniform_cutoff;
state->work_reg_count = program.work_register_count;
+ if (dev->quirks & IS_BIFROST)
+ for (unsigned i = 0; i < BIFROST_MAX_RENDER_TARGET_COUNT; i++)
+ state->blend_types[i] = bifrost_blend_type_from_nir(program.blend_types[i]);
+
unsigned default_vec1_swizzle = panfrost_get_default_swizzle(1);
unsigned default_vec2_swizzle = panfrost_get_default_swizzle(2);
unsigned default_vec4_swizzle = panfrost_get_default_swizzle(4);
diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c
index dfc5174bef5..439a09ca54c 100644
--- a/src/gallium/drivers/panfrost/pan_cmdstream.c
+++ b/src/gallium/drivers/panfrost/pan_cmdstream.c
@@ -615,7 +615,7 @@ panfrost_frag_meta_zsa_update(struct panfrost_context *ctx,
static void
panfrost_frag_meta_blend_update(struct panfrost_context *ctx,
struct mali_shader_meta *fragmeta,
- struct midgard_blend_rt *rts)
+ void *rts)
{
const struct panfrost_device *dev = pan_device(ctx->base.screen);
@@ -679,22 +679,56 @@ panfrost_frag_meta_blend_update(struct panfrost_context *ctx,
/* Additional blend descriptor tacked on for jobs using MFBD */
for (unsigned i = 0; i < rt_count; ++i) {
- rts[i].flags = 0x200;
+ if (dev->quirks & IS_BIFROST) {
+ struct bifrost_blend_rt *brts = rts;
+ struct panfrost_shader_state *fs;
+ fs = panfrost_get_shader_state(ctx, PIPE_SHADER_FRAGMENT);
+
+ brts[i].flags = 0x200;
+ if (blend[i].is_shader) {
+ /* The blend shader's address needs to be at
+ * the same top 32 bit as the fragment shader.
+ * TODO: Ensure that's always the case.
+ */
+ assert((blend[i].shader.gpu & (0xffffffffull << 32)) ==
+ (fs->bo->gpu & (0xffffffffull << 32)));
+ brts[i].shader = blend[i].shader.gpu;
+ brts[i].unk2 = 0x0;
+ } else {
+ enum pipe_format format = ctx->pipe_framebuffer.cbufs[i]->format;
+ const struct util_format_description *format_desc;
+ format_desc = util_format_description(format);
+
+ brts[i].equation = *blend[i].equation.equation;
+
+ /* TODO: this is a bit more complicated */
+ brts[i].constant = blend[i].equation.constant;
+
+ brts[i].format = panfrost_format_to_bifrost_blend(format_desc);
+ brts[i].unk2 = 0x19;
+
+ brts[i].shader_type = fs->blend_types[i];
+ }
+ } else {
+ struct midgard_blend_rt *mrts = rts;
- bool is_srgb = (ctx->pipe_framebuffer.nr_cbufs > i) &&
- (ctx->pipe_framebuffer.cbufs[i]) &&
- util_format_is_srgb(ctx->pipe_framebuffer.cbufs[i]->format);
+ mrts[i].flags = 0x200;
- SET_BIT(rts[i].flags, MALI_BLEND_MRT_SHADER, blend[i].is_shader);
- SET_BIT(rts[i].flags, MALI_BLEND_LOAD_TIB, !blend[i].no_blending);
- SET_BIT(rts[i].flags, MALI_BLEND_SRGB, is_srgb);
- SET_BIT(rts[i].flags, MALI_BLEND_NO_DITHER, !ctx->blend->base.dither);
+ bool is_srgb = (ctx->pipe_framebuffer.nr_cbufs > i) &&
+ (ctx->pipe_framebuffer.cbufs[i]) &&
+ util_format_is_srgb(ctx->pipe_framebuffer.cbufs[i]->format);
- if (blend[i].is_shader) {
- rts[i].blend.shader = blend[i].shader.gpu | blend[i].shader.first_tag;
- } else {
- rts[i].blend.equation = *blend[i].equation.equation;
- rts[i].blend.constant = blend[i].equation.constant;
+ SET_BIT(mrts[i].flags, MALI_BLEND_MRT_SHADER, blend[i].is_shader);
+ SET_BIT(mrts[i].flags, MALI_BLEND_LOAD_TIB, !blend[i].no_blending);
+ SET_BIT(mrts[i].flags, MALI_BLEND_SRGB, is_srgb);
+ SET_BIT(mrts[i].flags, MALI_BLEND_NO_DITHER, !ctx->blend->base.dither);
+
+ if (blend[i].is_shader) {
+ mrts[i].blend.shader = blend[i].shader.gpu | blend[i].shader.first_tag;
+ } else {
+ mrts[i].blend.equation = *blend[i].equation.equation;
+ mrts[i].blend.constant = blend[i].equation.constant;
+ }
}
}
}
@@ -702,7 +736,7 @@ panfrost_frag_meta_blend_update(struct panfrost_context *ctx,
static void
panfrost_frag_shader_meta_init(struct panfrost_context *ctx,
struct mali_shader_meta *fragmeta,
- struct midgard_blend_rt *rts)
+ void *rts)
{
const struct panfrost_device *dev = pan_device(ctx->base.screen);
struct panfrost_shader_state *fs;
@@ -779,20 +813,31 @@ panfrost_emit_shader_meta(struct panfrost_batch *batch,
struct panfrost_device *dev = pan_device(ctx->base.screen);
unsigned rt_count = MAX2(ctx->pipe_framebuffer.nr_cbufs, 1);
size_t desc_size = sizeof(meta);
- struct midgard_blend_rt rts[4];
+ void *rts = NULL;
struct panfrost_transfer xfer;
+ unsigned rt_size;
- assert(rt_count <= ARRAY_SIZE(rts));
+ if (dev->quirks & MIDGARD_SFBD)
+ rt_size = 0;
+ else if (dev->quirks & IS_BIFROST)
+ rt_size = sizeof(struct bifrost_blend_rt);
+ else
+ rt_size = sizeof(struct midgard_blend_rt);
- panfrost_frag_shader_meta_init(ctx, &meta, rts);
+ desc_size += rt_size * rt_count;
- if (!(dev->quirks & MIDGARD_SFBD))
- desc_size += sizeof(*rts) * rt_count;
+ if (rt_size)
+ rts = rzalloc_size(ctx, rt_size * rt_count);
+
+ panfrost_frag_shader_meta_init(ctx, &meta, rts);
xfer = panfrost_allocate_transient(batch, desc_size);
memcpy(xfer.cpu, &meta, sizeof(meta));
- memcpy(xfer.cpu + sizeof(meta), rts, sizeof(*rts) * rt_count);
+ memcpy(xfer.cpu + sizeof(meta), rts, rt_size * rt_count);
+
+ if (rt_size)
+ ralloc_free(rts);
shader_ptr = xfer.gpu;
} else {
diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h
index d43c202a855..c0a6d5fa1d6 100644
--- a/src/gallium/drivers/panfrost/pan_context.h
+++ b/src/gallium/drivers/panfrost/pan_context.h
@@ -195,6 +195,8 @@ struct panfrost_shader_state {
unsigned stack_size;
unsigned shared_size;
+ /* For Bifrost - output type for each RT */
+ enum bifrost_shader_type blend_types[BIFROST_MAX_RENDER_TARGET_COUNT];
unsigned int varying_count;
struct mali_attr_meta varyings[PIPE_MAX_ATTRIBS];