panfrost: XML-ify the blend descriptors
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6980>
This commit is contained in:
@@ -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 */
|
||||
|
@@ -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);
|
||||
|
@@ -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];
|
||||
|
@@ -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
|
||||
*
|
||||
|
@@ -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
|
||||
|
@@ -178,6 +178,74 @@
|
||||
<value name="RGB10 A2 2" value="238"/>
|
||||
</enum>
|
||||
|
||||
<enum name="RGB Component Order">
|
||||
<value name="RGBA" value="0"/>
|
||||
<value name="BRGA" value="2"/>
|
||||
<value name="BGRA" value="4"/>
|
||||
<value name="ARGB" value="8"/>
|
||||
<value name="RGB1" value="16"/>
|
||||
<value name="GRB1" value="18"/>
|
||||
<value name="BGR1" value="20"/>
|
||||
<value name="1RGB" value="24"/>
|
||||
<value name="1GRB" value="26"/>
|
||||
<value name="1BGR" value="28"/>
|
||||
<value name="Intensity" value="226"/>
|
||||
<value name="Luma" value="227"/>
|
||||
<value name="Luma Alpha" value="228"/>
|
||||
<value name="Alpha" value="229"/>
|
||||
<value name="Zero" value="231"/>
|
||||
<value name="Snap4 v9" value="232"/>
|
||||
<value name="Snap4 v10" value="233"/>
|
||||
<value name="Snap4 v11" value="234"/>
|
||||
<value name="Snap4 v12" value="235"/>
|
||||
<value name="Snap4 v13" value="236"/>
|
||||
<value name="Snap4 v14" value="237"/>
|
||||
<value name="Snap4 v15" value="238"/>
|
||||
<value name="Snap4 v16" value="239"/>
|
||||
<!-- Internal only, do not use -->
|
||||
<value name="R000" value="240"/>
|
||||
<value name="RBGA" value="242"/>
|
||||
</enum>
|
||||
|
||||
<enum name="YUV Swizzle">
|
||||
<value name="YUVA" value="0"/>
|
||||
<value name="YVUA" value="1"/>
|
||||
<value name="UYVA" value="2"/>
|
||||
<value name="UVYA" value="3"/>
|
||||
<value name="VUYA" value="4"/>
|
||||
<value name="VYUA" value="5"/>
|
||||
<value name="Y00A" value="6"/>
|
||||
<value name="YXXA" value="7"/>
|
||||
</enum>
|
||||
|
||||
<enum name="YUV Conversion Mode">
|
||||
<value name="No Conversion" value="0"/>
|
||||
<value name="BT 601" value="3"/>
|
||||
<value name="BT 709" value="4"/>
|
||||
<value name="BT 2020" value="6"/>
|
||||
</enum>
|
||||
|
||||
<enum name="YUV Cr Siting">
|
||||
<value name="Co-Sited" value="0"/>
|
||||
<value name="Center Y" value="1"/>
|
||||
<value name="Center X" value="2"/>
|
||||
<value name="Center" value="3"/>
|
||||
<value name="One Quarter" value="4"/>
|
||||
<value name="Three Quarters" value="5"/>
|
||||
<value name="Replicated" value="7"/>
|
||||
</enum>
|
||||
|
||||
<struct name="Pixel Format" no-direct-packing="true">
|
||||
<field name="RGB Component Order" size="8" start="0" type="RGB Component Order"/>
|
||||
<field name="YUV Component Order" size="3" start="0" type="YUV Swizzle"/>
|
||||
<field name="YUV Component Swap" size="1" start="3" type="bool"/>
|
||||
<field name="YUV Cr Siting" size="3" start="0" type="YUV Cr Siting"/>
|
||||
<field name="Swizzle" size="12" start="0" type="uint"/>
|
||||
<field name="Format" size="8" start="12" type="Format"/>
|
||||
<field name="sRGB" size="1" start="20" type="bool"/>
|
||||
<field name="Big Endian" size="1" start="21" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<enum name="Block Format">
|
||||
<!--- 16x16 block u-interleaved -->
|
||||
<value name="Tiled U-Interleaved" value="0"/>
|
||||
@@ -324,19 +392,67 @@
|
||||
<field name="Color Mask" size="4" start="0:28" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="Blend Flags" size="1">
|
||||
<field name="Load destination" size="1" start="0" type="bool" default="false"/>
|
||||
<field name="Midgard blend shader" size="1" start="1" type="bool" default="false"/>
|
||||
<field name="Enable" size="1" start="9" type="bool" default="true"/>
|
||||
<field name="sRGB" size="1" start="10" type="bool" default="false"/>
|
||||
<field name="Round to FB precision" size="1" start="11" type="bool" default="false"/>
|
||||
</struct>
|
||||
|
||||
<struct name="Midgard Blend" size="4">
|
||||
<field name="Flags" size="32" start="0:0" type="Blend Flags"/>
|
||||
<struct name="Midgard Blend Overlay" size="4" no-direct-packing="true">
|
||||
<field name="Blend Shader" size="1" start="0:1" type="bool" default="false"/>
|
||||
<field name="Blend Shader Contains Discard" size="1" start="0:2" type="bool" default="false"/>
|
||||
<field name="Shader PC" size="64" start="2:0" type="address"/>
|
||||
<field name="Equation" size="32" start="2:0" type="Blend Equation"/>
|
||||
<field name="Constant" size="32" start="3:0" type="float"/>
|
||||
<field name="Shader" size="64" start="2:0" type="address"/>
|
||||
</struct>
|
||||
|
||||
<enum name="Bifrost Register File Format">
|
||||
<value name="F16" value="0"/>
|
||||
<value name="F32" value="1"/>
|
||||
<value name="I32" value="2"/>
|
||||
<value name="U32" value="3"/>
|
||||
<value name="I16" value="4"/>
|
||||
<value name="U16" value="5"/>
|
||||
</enum>
|
||||
|
||||
<enum name="Bifrost Blend Mode">
|
||||
<value name="Shader" value="0"/>
|
||||
<value name="Opaque" value="1"/>
|
||||
<value name="Fixed-Function" value="2"/>
|
||||
<value name="Off" value="3"/>
|
||||
</enum>
|
||||
|
||||
<struct name="Bifrost Blend Shader" size="2">
|
||||
<field name="Return Value" size="29" start="0:3" type="uint" modifier="shr(3)"/>
|
||||
<field name="PC" size="28" start="1:4" type="uint" modifier="shr(4)"/>
|
||||
</struct>
|
||||
|
||||
<struct name="Bifrost Internal Conversion" size="1">
|
||||
<field name="Memory Format" size="22" start="0" type="Pixel Format"/>
|
||||
<field name="Raw" size="1" start="22" type="bool"/>
|
||||
<field name="Register Format" size="3" start="24" type="Bifrost Register File Format"/>
|
||||
</struct>
|
||||
|
||||
<struct name="Bifrost Blend Fixed-Function" size="2">
|
||||
<field name="Num Comps" size="2" start="0:3" type="uint" modifier="minus(1)" default="1"/>
|
||||
<field name="Alpha Zero NOP" size="1" start="0:5" type="bool"/>
|
||||
<field name="Alpha One Store" size="1" start="0:6" type="bool"/>
|
||||
<field name="RT" size="4" start="0:16" type="uint">
|
||||
<value name="MALI_BIFROST_BLEND_MAX_RT" value="8"/>
|
||||
</field>
|
||||
<field name="Conversion" size="32" start="1:0" type="Bifrost Internal Conversion"/>
|
||||
</struct>
|
||||
|
||||
<struct name="Bifrost Blend Overlay" no-direct-packing="true">
|
||||
<field name="Constant" size="16" start="0:16" type="uint"/>
|
||||
<field name="Equation" size="32" start="1:0" type="Blend Equation"/>
|
||||
<field name="Mode" size="2" start="2:0" type="Bifrost Blend Mode"/>
|
||||
<field name="Shader" size="64" start="2:0" type="Bifrost Blend Shader"/>
|
||||
<field name="Fixed-Function" size="64" start="2:0" type="Bifrost Blend Fixed-Function"/>
|
||||
</struct>
|
||||
|
||||
<struct name="Blend" size="4">
|
||||
<field name="Load Destination" size="1" start="0:0" type="bool" default="false"/>
|
||||
<field name="Alpha To One" size="1" start="0:8" type="bool"/>
|
||||
<field name="Enable" size="1" start="0:9" type="bool" default="true"/>
|
||||
<field name="sRGB" size="1" start="0:10" type="bool" default="false"/>
|
||||
<field name="Round to FB precision" size="1" start="0:11" type="bool" default="false"/>
|
||||
<field name="Midgard" size="1" start="0:0" type="Midgard Blend Overlay"/>
|
||||
<field name="Bifrost" size="1" start="0:0" type="Bifrost Blend Overlay"/>
|
||||
</struct>
|
||||
|
||||
<struct name="Invocation">
|
||||
@@ -938,33 +1054,6 @@
|
||||
<value name="256" value="1"/>
|
||||
</enum>
|
||||
|
||||
<enum name="YUV Swizzle">
|
||||
<value name="YUVA" value="0"/>
|
||||
<value name="YVUA" value="1"/>
|
||||
<value name="UYVA" value="2"/>
|
||||
<value name="UVYA" value="3"/>
|
||||
<value name="VUYA" value="4"/>
|
||||
<value name="VYUA" value="5"/>
|
||||
<value name="Y00A" value="6"/>
|
||||
<value name="YXXA" value="7"/>
|
||||
</enum>
|
||||
|
||||
<enum name="YUV Conversion Mode">
|
||||
<value name="No Conversion" value="0"/>
|
||||
<value name="BT 601" value="3"/>
|
||||
<value name="BT 709" value="4"/>
|
||||
<value name="BT 2020" value="6"/>
|
||||
</enum>
|
||||
|
||||
<enum name="YUV Cr Siting">
|
||||
<value name="Co-Sited" value="0"/>
|
||||
<value name="Center Y" value="1"/>
|
||||
<value name="Center X" value="2"/>
|
||||
<value name="Center" value="3"/>
|
||||
<value name="One Quarter" value="4"/>
|
||||
<value name="Three Quarters" value="5"/>
|
||||
</enum>
|
||||
|
||||
<struct name="Render Target Midgard Overlay" size="16">
|
||||
<field name="Writeback Endianness" size="2" start="1:8" type="RT Endianness"/>
|
||||
<field name="Writeback Block Format" size="2" start="1:10" type="Block Format"/>
|
||||
|
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user