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)); } }