diff --git a/src/gallium/drivers/panfrost/pan_assemble.c b/src/gallium/drivers/panfrost/pan_assemble.c
index 939e73d16fd..494976d04d8 100644
--- a/src/gallium/drivers/panfrost/pan_assemble.c
+++ b/src/gallium/drivers/panfrost/pan_assemble.c
@@ -189,24 +189,24 @@ pan_format_from_glsl(const struct glsl_type *type, unsigned precision, unsigned
MALI_NR_CHANNELS(chan);
}
-static enum bifrost_shader_type
+static enum mali_bifrost_register_file_format
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;
+ return MALI_BIFROST_REGISTER_FILE_FORMAT_F16;
case nir_type_float32:
- return BIFROST_BLEND_F32;
+ return MALI_BIFROST_REGISTER_FILE_FORMAT_F32;
case nir_type_int32:
- return BIFROST_BLEND_I32;
+ return MALI_BIFROST_REGISTER_FILE_FORMAT_I32;
case nir_type_uint32:
- return BIFROST_BLEND_U32;
+ return MALI_BIFROST_REGISTER_FILE_FORMAT_U32;
case nir_type_int16:
- return BIFROST_BLEND_I16;
+ return MALI_BIFROST_REGISTER_FILE_FORMAT_I16;
case nir_type_uint16:
- return BIFROST_BLEND_U16;
+ return MALI_BIFROST_REGISTER_FILE_FORMAT_U16;
default:
unreachable("Unsupported blend shader type for NIR alu type");
return 0;
@@ -339,7 +339,7 @@ panfrost_shader_compile(struct panfrost_context *ctx,
state->work_reg_count = program.work_register_count;
if (dev->quirks & IS_BIFROST)
- for (unsigned i = 0; i < BIFROST_MAX_RENDER_TARGET_COUNT; i++)
+ for (unsigned i = 0; i < ARRAY_SIZE(state->blend_types); i++)
state->blend_types[i] = bifrost_blend_type_from_nir(program.blend_types[i]);
/* Record the varying mapping for the command stream's bookkeeping */
diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c
index fd0b6ad1e77..7e68c10af89 100644
--- a/src/gallium/drivers/panfrost/pan_cmdstream.c
+++ b/src/gallium/drivers/panfrost/pan_cmdstream.c
@@ -265,13 +265,14 @@ panfrost_emit_bifrost_blend(struct panfrost_batch *batch,
struct panfrost_blend_final *blend,
void *rts)
{
- struct bifrost_blend_rt *brts = rts;
unsigned rt_count = batch->key.nr_cbufs;
if (rt_count == 0) {
/* Disable blending for depth-only */
- memset(rts, 0, sizeof(*brts));
- brts[0].unk2 = 0x3;
+ pan_pack(rts, BLEND, cfg) {
+ cfg.enable = false;
+ cfg.bifrost.mode = MALI_BIFROST_BLEND_MODE_OFF;
+ }
return;
}
@@ -279,9 +280,7 @@ panfrost_emit_bifrost_blend(struct panfrost_batch *batch,
struct panfrost_shader_state *fs = panfrost_get_shader_state(batch->ctx, PIPE_SHADER_FRAGMENT);
for (unsigned i = 0; i < rt_count; ++i) {
- struct mali_blend_flags_packed flags = {0};
-
- pan_pack(&flags, BLEND_FLAGS, cfg) {
+ pan_pack(rts + i * MALI_BLEND_LENGTH, BLEND, cfg) {
if (blend[i].no_colour) {
cfg.enable = false;
} else {
@@ -289,45 +288,47 @@ panfrost_emit_bifrost_blend(struct panfrost_batch *batch,
cfg.load_destination = blend[i].load_dest;
cfg.round_to_fb_precision = !batch->ctx->blend->base.dither;
}
- }
- memset(rts + i, 0, sizeof(rts[i]));
- brts[i].flags = flags.opaque[0];
+ 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)));
+ cfg.bifrost.shader.pc = (u32)blend[i].shader.gpu;
+ cfg.bifrost.mode = MALI_BIFROST_BLEND_MODE_SHADER;
+ } else {
+ enum pipe_format format = batch->key.cbufs[i]->format;
+ const struct util_format_description *format_desc;
+ unsigned chan_size = 0;
- 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 = batch->key.cbufs[i]->format;
- const struct util_format_description *format_desc;
- format_desc = util_format_description(format);
- struct mali_blend_equation_packed peq;
+ format_desc = util_format_description(format);
- pan_pack(&peq, BLEND_EQUATION, cfg) {
- cfg = blend[i].equation.equation;
+ for (unsigned i = 0; i < format_desc->nr_channels; i++)
+ chan_size = MAX2(format_desc->channel[0].size, chan_size);
+
+ cfg.bifrost.equation = blend[i].equation.equation;
+
+ /* Fixed point constant */
+ u16 constant = blend[i].equation.constant / ((1 << chan_size) - 1);
+ constant <<= 16 - chan_size;
+ cfg.bifrost.constant = constant;
+
+ if (blend[i].opaque)
+ cfg.bifrost.mode = MALI_BIFROST_BLEND_MODE_OPAQUE;
+ else
+ cfg.bifrost.mode = MALI_BIFROST_BLEND_MODE_FIXED_FUNCTION;
+
+ cfg.bifrost.fixed_function.num_comps = format_desc->nr_channels;
+ cfg.bifrost.fixed_function.conversion.memory_format.format =
+ panfrost_format_to_bifrost_blend(format_desc);
+ if (dev->quirks & HAS_SWIZZLES) {
+ cfg.bifrost.fixed_function.conversion.memory_format.swizzle =
+ panfrost_get_default_swizzle(4);
+ }
+ cfg.bifrost.fixed_function.conversion.register_format = fs->blend_types[i];
}
- brts[i].equation = peq;
-
- /* TODO: this is a bit more complicated */
- brts[i].constant = blend[i].equation.constant;
-
- brts[i].format = panfrost_format_to_bifrost_blend(format_desc);
- if (dev->quirks & HAS_SWIZZLES)
- brts[i].swizzle = panfrost_get_default_swizzle(4);
-
- /* 0x19 disables blending and forces REPLACE
- * mode (equivalent to rgb_mode = alpha_mode =
- * x122, colour mask = 0xF). 0x1a allows
- * blending. */
- brts[i].unk2 = blend[i].opaque ? 0x19 : 0x1a;
-
- brts[i].shader_type = fs->blend_types[i];
}
}
}
@@ -341,34 +342,34 @@ panfrost_emit_midgard_blend(struct panfrost_batch *batch,
if (rt_count == 0) {
/* Disable blending for depth-only */
- pan_pack(rts, MIDGARD_BLEND, cfg) {
- cfg.equation.color_mask = 0xf;
- cfg.equation.rgb.a = MALI_BLEND_OPERAND_A_SRC;
- cfg.equation.rgb.b = MALI_BLEND_OPERAND_B_SRC;
- cfg.equation.rgb.c = MALI_BLEND_OPERAND_C_ZERO;
- cfg.equation.alpha.a = MALI_BLEND_OPERAND_A_SRC;
- cfg.equation.alpha.b = MALI_BLEND_OPERAND_B_SRC;
- cfg.equation.alpha.c = MALI_BLEND_OPERAND_C_ZERO;
+ pan_pack(rts, BLEND, cfg) {
+ cfg.midgard.equation.color_mask = 0xf;
+ cfg.midgard.equation.rgb.a = MALI_BLEND_OPERAND_A_SRC;
+ cfg.midgard.equation.rgb.b = MALI_BLEND_OPERAND_B_SRC;
+ cfg.midgard.equation.rgb.c = MALI_BLEND_OPERAND_C_ZERO;
+ cfg.midgard.equation.alpha.a = MALI_BLEND_OPERAND_A_SRC;
+ cfg.midgard.equation.alpha.b = MALI_BLEND_OPERAND_B_SRC;
+ cfg.midgard.equation.alpha.c = MALI_BLEND_OPERAND_C_ZERO;
}
return;
}
for (unsigned i = 0; i < rt_count; ++i) {
- pan_pack(rts + i * MALI_MIDGARD_BLEND_LENGTH, MIDGARD_BLEND, cfg) {
+ pan_pack(rts + i * MALI_BLEND_LENGTH, BLEND, cfg) {
if (blend[i].no_colour) {
- cfg.flags.enable = false;
+ cfg.enable = false;
continue;
}
- cfg.flags.srgb = util_format_is_srgb(batch->key.cbufs[i]->format);
- cfg.flags.load_destination = blend[i].load_dest;
- cfg.flags.round_to_fb_precision = !batch->ctx->blend->base.dither;
- cfg.flags.midgard_blend_shader = blend[i].is_shader;
+ cfg.srgb = util_format_is_srgb(batch->key.cbufs[i]->format);
+ cfg.load_destination = blend[i].load_dest;
+ cfg.round_to_fb_precision = !batch->ctx->blend->base.dither;
+ cfg.midgard.blend_shader = blend[i].is_shader;
if (blend[i].is_shader) {
- cfg.shader = blend[i].shader.gpu | blend[i].shader.first_tag;
+ cfg.midgard.shader_pc = blend[i].shader.gpu | blend[i].shader.first_tag;
} else {
- cfg.equation = blend[i].equation.equation;
- cfg.constant = blend[i].equation.constant;
+ cfg.midgard.equation = blend[i].equation.equation;
+ cfg.midgard.constant = blend[i].equation.constant;
}
}
}
@@ -586,10 +587,8 @@ panfrost_emit_frag_shader_meta(struct panfrost_batch *batch)
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);
+ rt_size = MALI_BLEND_LENGTH;
unsigned desc_size = MALI_RENDERER_STATE_LENGTH + rt_size * rt_count;
xfer = panfrost_pool_alloc_aligned(&batch->pool, desc_size, MALI_RENDERER_STATE_LENGTH);
diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h
index c9f0c1bdb35..50fddffaaf2 100644
--- a/src/gallium/drivers/panfrost/pan_context.h
+++ b/src/gallium/drivers/panfrost/pan_context.h
@@ -34,6 +34,7 @@
#include "pan_blend.h"
#include "pan_encoder.h"
#include "pan_texture.h"
+#include "midgard_pack.h"
#include "pipe/p_compiler.h"
#include "pipe/p_config.h"
@@ -225,7 +226,7 @@ struct panfrost_shader_state {
bool fs_sidefx;
/* For Bifrost - output type for each RT */
- enum bifrost_shader_type blend_types[BIFROST_MAX_RENDER_TARGET_COUNT];
+ enum mali_bifrost_register_file_format blend_types[MALI_BIFROST_BLEND_MAX_RT];
unsigned attribute_count, varying_count, ubo_count;
enum mali_format varyings[PIPE_MAX_ATTRIBS];
diff --git a/src/panfrost/include/panfrost-job.h b/src/panfrost/include/panfrost-job.h
index 1482ce75b88..5fbe31c0f12 100644
--- a/src/panfrost/include/panfrost-job.h
+++ b/src/panfrost/include/panfrost-job.h
@@ -99,100 +99,6 @@ typedef uint64_t mali_ptr;
/* The raw Midgard blend payload can either be an equation or a shader
* address, depending on the context */
-union midgard_blend {
- mali_ptr shader;
-
- struct {
- struct mali_blend_equation_packed equation;
- float constant;
- };
-};
-
-struct midgard_blend_rt {
- struct mali_blend_flags_packed flags;
- u32 zero;
- union midgard_blend blend;
-} __attribute__((packed));
-
-/* On Bifrost systems (all MRT), each render target gets one of these
- * descriptors */
-
-enum bifrost_shader_type {
- BIFROST_BLEND_F16 = 0,
- BIFROST_BLEND_F32 = 1,
- BIFROST_BLEND_I32 = 2,
- BIFROST_BLEND_U32 = 3,
- BIFROST_BLEND_I16 = 4,
- BIFROST_BLEND_U16 = 5,
-};
-
-#define BIFROST_MAX_RENDER_TARGET_COUNT 8
-
-struct bifrost_blend_rt {
- /* This is likely an analogue of the flags on
- * midgard_blend_rt */
-
- u16 flags; // = 0x200
-
- /* Single-channel blend constants are encoded in a sort of
- * fixed-point. Basically, the float is mapped to a byte, becoming
- * a high byte, and then the lower-byte is added for precision.
- * For the original float f:
- *
- * f = (constant_hi / 255) + (constant_lo / 65535)
- *
- * constant_hi = int(f / 255)
- * constant_lo = 65535*f - (65535/255) * constant_hi
- */
- u16 constant;
-
- struct mali_blend_equation_packed equation;
-
- /*
- * - 0x19 normally
- * - 0x3 when this slot is unused (everything else is 0 except the index)
- * - 0x11 when this is the fourth slot (and it's used)
- * - 0 when there is a blend shader
- */
- u16 unk2;
-
- /* increments from 0 to 3 */
- u16 index;
-
- union {
- struct {
- /* So far, I've only seen:
- * - R001 for 1-component formats
- * - RG01 for 2-component formats
- * - RGB1 for 3-component formats
- * - RGBA for 4-component formats
- */
- u32 swizzle : 12;
- enum mali_format format : 8;
-
- /* Type of the shader output variable. Note, this can
- * be different from the format.
- * enum bifrost_shader_type
- */
- u32 zero1 : 4;
- u32 shader_type : 3;
- u32 zero2 : 5;
- };
-
- /* Only the low 32 bits of the blend shader are stored, the
- * high 32 bits are implicitly the same as the original shader.
- * According to the kernel driver, the program counter for
- * shaders is actually only 24 bits, so shaders cannot cross
- * the 2^24-byte boundary, and neither can the blend shader.
- * The blob handles this by allocating a 2^24 byte pool for
- * shaders, and making sure that any blend shaders are stored
- * in the same pool as the original shader. The kernel will
- * make sure this allocation is aligned to 2^24 bytes.
- */
- u32 shader;
- };
-} __attribute__((packed));
-
/*
* Mali Attributes
*
diff --git a/src/panfrost/lib/decode.c b/src/panfrost/lib/decode.c
index e6d35b65972..05afc871208 100644
--- a/src/panfrost/lib/decode.c
+++ b/src/panfrost/lib/decode.c
@@ -39,8 +39,6 @@
#include "pan_encoder.h"
-static void pandecode_swizzle(unsigned swizzle, enum mali_format format);
-
#define MEMORY_PROP(obj, p) {\
if (obj->p) { \
char *a = pointer_as_memory_reference(obj->p); \
@@ -334,101 +332,6 @@ pandecode_compute_fbd(uint64_t gpu_va, int job_no)
DUMP_CL(LOCAL_STORAGE, s, "Local Storage:\n");
}
-/* Extracts the number of components associated with a Mali format */
-
-static unsigned
-pandecode_format_component_count(enum mali_format fmt)
-{
- /* Mask out the format class */
- unsigned top = fmt & 0b11100000;
-
- switch (top) {
- case MALI_FORMAT_SNORM:
- case MALI_FORMAT_UINT:
- case MALI_FORMAT_UNORM:
- case MALI_FORMAT_SINT:
- return ((fmt >> 3) & 3) + 1;
- default:
- /* TODO: Validate */
- return 4;
- }
-}
-
-/* Extracts a mask of accessed components from a 12-bit Mali swizzle */
-
-static unsigned
-pandecode_access_mask_from_channel_swizzle(unsigned swizzle)
-{
- unsigned mask = 0;
- assert(MALI_CHANNEL_R == 0);
-
- for (unsigned c = 0; c < 4; ++c) {
- enum mali_channel chan = (swizzle >> (3*c)) & 0x7;
-
- if (chan <= MALI_CHANNEL_A)
- mask |= (1 << chan);
- }
-
- return mask;
-}
-
-/* Validates that a (format, swizzle) pair is valid, in the sense that the
- * swizzle doesn't access any components that are undefined in the format.
- * Returns whether the swizzle is trivial (doesn't do any swizzling) and can be
- * omitted */
-
-static bool
-pandecode_validate_format_swizzle(enum mali_format fmt, unsigned swizzle)
-{
- unsigned nr_comp = pandecode_format_component_count(fmt);
- unsigned access_mask = pandecode_access_mask_from_channel_swizzle(swizzle);
- unsigned valid_mask = (1 << nr_comp) - 1;
- unsigned invalid_mask = ~valid_mask;
-
- if (access_mask & invalid_mask) {
- pandecode_msg("XXX: invalid components accessed\n");
- return false;
- }
-
- /* Check for the default non-swizzling swizzle so we can suppress
- * useless printing for the defaults */
-
- unsigned default_swizzles[4] = {
- MALI_CHANNEL_R | (MALI_CHANNEL_0 << 3) | (MALI_CHANNEL_0 << 6) | (MALI_CHANNEL_1 << 9),
- MALI_CHANNEL_R | (MALI_CHANNEL_G << 3) | (MALI_CHANNEL_0 << 6) | (MALI_CHANNEL_1 << 9),
- MALI_CHANNEL_R | (MALI_CHANNEL_G << 3) | (MALI_CHANNEL_B << 6) | (MALI_CHANNEL_1 << 9),
- MALI_CHANNEL_R | (MALI_CHANNEL_G << 3) | (MALI_CHANNEL_B << 6) | (MALI_CHANNEL_A << 9)
- };
-
- return (swizzle == default_swizzles[nr_comp - 1]);
-}
-
-static void
-pandecode_swizzle(unsigned swizzle, enum mali_format format)
-{
- /* First, do some validation */
- bool trivial_swizzle = pandecode_validate_format_swizzle(
- format, swizzle);
-
- if (trivial_swizzle)
- return;
-
- /* Next, print the swizzle */
- pandecode_log_cont(".");
-
- static const char components[] = "rgba01";
-
- for (unsigned c = 0; c < 4; ++c) {
- enum mali_channel chan = (swizzle >> (3 * c)) & 0x7;
-
- if (chan > MALI_CHANNEL_1) {
- pandecode_log("XXX: invalid swizzle channel %d\n", chan);
- continue;
- }
- pandecode_log_cont("%c", components[chan]);
- }
-}
-
static void
pandecode_render_target(uint64_t gpu_va, unsigned job_no, bool is_bifrost, unsigned gpu_id,
const struct MALI_MULTI_TARGET_FRAMEBUFFER_PARAMETERS *fb)
@@ -589,128 +492,23 @@ pandecode_shader_address(const char *name, mali_ptr ptr)
/* Decodes a Bifrost blend constant. See the notes in bifrost_blend_rt */
-static float
-decode_bifrost_constant(u16 constant)
-{
- float lo = (float) (constant & 0xFF);
- float hi = (float) (constant >> 8);
-
- return (hi / 255.0) + (lo / 65535.0);
-}
-
static mali_ptr
-pandecode_bifrost_blend(void *descs, int job_no, int rt_no)
+pandecode_bifrost_blend(void *descs, int job_no, int rt_no, mali_ptr frag_shader)
{
- struct bifrost_blend_rt *b =
- ((struct bifrost_blend_rt *) descs) + rt_no;
-
- pandecode_log("struct bifrost_blend_rt blend_rt_%d_%d = {\n", job_no, rt_no);
- pandecode_indent++;
-
- pandecode_prop("flags = 0x%" PRIx16, b->flags);
- pandecode_prop("constant = 0x%" PRIx8 " /* %f */",
- b->constant, decode_bifrost_constant(b->constant));
-
- /* TODO figure out blend shader enable bit */
- DUMP_CL(BLEND_EQUATION, &b->equation, "Equation:\n");
-
- pandecode_prop("unk2 = 0x%" PRIx16, b->unk2);
- pandecode_prop("index = 0x%" PRIx16, b->index);
-
- pandecode_log(".format = %s", mali_format_as_str(b->format));
- pandecode_swizzle(b->swizzle, b->format);
- pandecode_log_cont(",\n");
-
- pandecode_prop("swizzle = 0x%" PRIx32, b->swizzle);
- pandecode_prop("format = 0x%" PRIx32, b->format);
-
- if (b->zero1) {
- pandecode_msg("XXX: pandecode_bifrost_blend zero1 tripped\n");
- pandecode_prop("zero1 = 0x%" PRIx32, b->zero1);
- }
-
- pandecode_log(".shader_type = ");
- switch(b->shader_type) {
- case BIFROST_BLEND_F16:
- pandecode_log_cont("BIFROST_BLEND_F16");
- break;
- case BIFROST_BLEND_F32:
- pandecode_log_cont("BIFROST_BLEND_F32");
- break;
- case BIFROST_BLEND_I32:
- pandecode_log_cont("BIFROST_BLEND_I32");
- break;
- case BIFROST_BLEND_U32:
- pandecode_log_cont("BIFROST_BLEND_U32");
- break;
- case BIFROST_BLEND_I16:
- pandecode_log_cont("BIFROST_BLEND_I16");
- break;
- case BIFROST_BLEND_U16:
- pandecode_log_cont("BIFROST_BLEND_U16");
- break;
- }
- pandecode_log_cont(",\n");
-
- if (b->zero2) {
- pandecode_msg("XXX: pandecode_bifrost_blend zero2 tripped\n");
- pandecode_prop("zero2 = 0x%" PRIx32, b->zero2);
- }
-
- pandecode_prop("shader = 0x%" PRIx32, b->shader);
-
- pandecode_indent--;
- pandecode_log("},\n");
-
- return 0;
-}
-
-static mali_ptr
-pandecode_midgard_blend(union midgard_blend *blend, bool is_shader)
-{
- /* constant/equation is in a union */
- if (!blend->shader)
+ pan_unpack(descs + (rt_no * MALI_BLEND_LENGTH), BLEND, b);
+ DUMP_UNPACKED(BLEND, b, "Blend RT %d:\n", rt_no);
+ if (b.bifrost.mode != MALI_BIFROST_BLEND_MODE_SHADER)
return 0;
- pandecode_log(".blend = {\n");
- pandecode_indent++;
-
- if (is_shader) {
- pandecode_shader_address("shader", blend->shader);
- } else {
- DUMP_CL(BLEND_EQUATION, &blend->equation, "Equation:\n");
- pandecode_prop("constant = %f", blend->constant);
- }
-
- pandecode_indent--;
- pandecode_log("},\n");
-
- /* Return blend shader to disassemble if present */
- return is_shader ? (blend->shader & ~0xF) : 0;
+ return (frag_shader & 0xFFFFFFFF00000000ULL) | b.bifrost.shader.pc;
}
static mali_ptr
pandecode_midgard_blend_mrt(void *descs, int job_no, int rt_no)
{
- struct midgard_blend_rt *b =
- ((struct midgard_blend_rt *) descs) + rt_no;
-
- /* Flags determine presence of blend shader */
- bool is_shader = b->flags.opaque[0] & 0x2;
-
- pandecode_log("struct midgard_blend_rt blend_rt_%d_%d = {\n", job_no, rt_no);
- pandecode_indent++;
-
- DUMP_CL(BLEND_FLAGS, &b->flags, "Flags:\n");
-
- union midgard_blend blend = b->blend;
- mali_ptr shader = pandecode_midgard_blend(&blend, is_shader);
-
- pandecode_indent--;
- pandecode_log("};\n");
- pandecode_log("\n");
-
- return shader;
+ pan_unpack(descs + (rt_no * MALI_BLEND_LENGTH), BLEND, b);
+ DUMP_UNPACKED(BLEND, b, "Blend RT %d:\n", rt_no);
+ return b.midgard.blend_shader ? (b.midgard.shader_pc & ~0xf) : 0;
}
/* Attributes and varyings have descriptor records, which contain information
@@ -1214,13 +1012,14 @@ pandecode_vertex_tiler_postfix_pre(
mali_ptr shader = 0;
if (is_bifrost)
- shader = pandecode_bifrost_blend(blend_base, job_no, i);
- else
+ shader = pandecode_bifrost_blend(blend_base, job_no, i,
+ state.shader.shader);
+ else
shader = pandecode_midgard_blend_mrt(blend_base, job_no, i);
if (shader & ~0xF)
- pandecode_blend_shader_disassemble(shader, job_no, job_type, false, gpu_id);
-
+ pandecode_blend_shader_disassemble(shader, job_no, job_type,
+ is_bifrost, gpu_id);
}
}
} else
diff --git a/src/panfrost/lib/midgard.xml b/src/panfrost/lib/midgard.xml
index 75aa3f2eaa5..6dc74728621 100644
--- a/src/panfrost/lib/midgard.xml
+++ b/src/panfrost/lib/midgard.xml
@@ -178,6 +178,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -324,19 +392,67 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -938,33 +1054,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/panfrost/lib/pan_blit.c b/src/panfrost/lib/pan_blit.c
index 8f30b05c478..626e761d75c 100644
--- a/src/panfrost/lib/pan_blit.c
+++ b/src/panfrost/lib/pan_blit.c
@@ -218,8 +218,11 @@ panfrost_load_midg(
bool ms = image->nr_samples > 1;
- struct panfrost_transfer shader_meta_t = panfrost_pool_alloc_aligned(
- pool, MALI_RENDERER_STATE_LENGTH + 8 * sizeof(struct midgard_blend_rt), 128);
+ struct panfrost_transfer shader_meta_t =
+ panfrost_pool_alloc_aligned(pool,
+ MALI_RENDERER_STATE_LENGTH +
+ 8 * MALI_BLEND_LENGTH,
+ 128);
pan_pack(shader_meta_t.cpu, RENDERER_STATE, cfg) {
cfg.shader.shader = pool->dev->blit_shaders.loads[loc][T][ms];
@@ -308,45 +311,29 @@ panfrost_load_midg(
cfg.normalized_coordinates = false;
for (unsigned i = 0; i < 8; ++i) {
- void *dest = shader_meta_t.cpu + MALI_RENDERER_STATE_LENGTH + sizeof(struct midgard_blend_rt) * i;
+ void *dest = shader_meta_t.cpu + MALI_RENDERER_STATE_LENGTH +
+ MALI_BLEND_LENGTH * i;
- if (loc == (FRAG_RESULT_DATA0 + i)) {
- struct mali_blend_equation_packed eq;
+ if (loc != (FRAG_RESULT_DATA0 + i)) {
+ memset(dest, 0x0, MALI_BLEND_LENGTH);
+ continue;
+ }
- pan_pack(&eq, BLEND_EQUATION, cfg) {
- cfg.rgb.a = MALI_BLEND_OPERAND_A_SRC;
- cfg.rgb.b = MALI_BLEND_OPERAND_B_SRC;
- cfg.rgb.c = MALI_BLEND_OPERAND_C_ZERO;
- cfg.alpha.a = MALI_BLEND_OPERAND_A_SRC;
- cfg.alpha.b = MALI_BLEND_OPERAND_B_SRC;
- cfg.alpha.c = MALI_BLEND_OPERAND_C_ZERO;
-
- if (loc >= FRAG_RESULT_DATA0)
- cfg.color_mask = 0xf;
+ pan_pack(dest, BLEND, cfg) {
+ cfg.round_to_fb_precision = true;
+ cfg.srgb = srgb;
+ if (blend_shader) {
+ cfg.midgard.blend_shader = true;
+ cfg.midgard.shader_pc = blend_shader;
+ } else {
+ cfg.midgard.equation.rgb.a = MALI_BLEND_OPERAND_A_SRC;
+ cfg.midgard.equation.rgb.b = MALI_BLEND_OPERAND_B_SRC;
+ cfg.midgard.equation.rgb.c = MALI_BLEND_OPERAND_C_ZERO;
+ cfg.midgard.equation.alpha.a = MALI_BLEND_OPERAND_A_SRC;
+ cfg.midgard.equation.alpha.b = MALI_BLEND_OPERAND_B_SRC;
+ cfg.midgard.equation.alpha.c = MALI_BLEND_OPERAND_C_ZERO;
+ cfg.midgard.equation.color_mask = 0xf;
}
-
- union midgard_blend replace = {
- .equation = eq
- };
-
- struct midgard_blend_rt blend_rt = {
- .blend = replace,
- };
-
- unsigned flags = 0;
- pan_pack(&flags, BLEND_FLAGS, cfg) {
- cfg.round_to_fb_precision = true;
- cfg.srgb = srgb;
- cfg.midgard_blend_shader = blend_shader;
- }
- blend_rt.flags.opaque[0] = flags;
-
- if (blend_shader)
- blend_rt.blend.shader = blend_shader;
-
- memcpy(dest, &blend_rt, sizeof(struct midgard_blend_rt));
- } else {
- memset(dest, 0x0, sizeof(struct midgard_blend_rt));
}
}