panfrost: XML-ify the midgard tiler descriptor

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/6797>
This commit is contained in:
Boris Brezillon 2020-09-05 18:16:37 +02:00 committed by Alyssa Rosenzweig
parent fb95729b69
commit e855698ddd
8 changed files with 123 additions and 142 deletions

View file

@ -48,6 +48,7 @@
#include "tgsi/tgsi_from_mesa.h"
#include "util/u_math.h"
#include "midgard_pack.h"
#include "pan_screen.h"
#include "pan_blending.h"
#include "pan_blend_shaders.h"
@ -56,64 +57,67 @@
#include "decode.h"
#include "util/pan_lower_framebuffer.h"
struct midgard_tiler_descriptor
panfrost_emit_midg_tiler(struct panfrost_batch *batch, unsigned vertex_count)
void
panfrost_emit_midg_tiler(struct panfrost_batch *batch,
struct mali_midgard_tiler_packed *tp,
unsigned vertex_count)
{
struct panfrost_device *device = pan_device(batch->ctx->base.screen);
bool hierarchy = !(device->quirks & MIDGARD_NO_HIER_TILING);
struct midgard_tiler_descriptor t = {0};
unsigned height = batch->key.height;
unsigned width = batch->key.width;
t.hierarchy_mask =
panfrost_choose_hierarchy_mask(width, height, vertex_count, hierarchy);
pan_pack(tp, MIDGARD_TILER, t) {
t.hierarchy_mask =
panfrost_choose_hierarchy_mask(width, height,
vertex_count, hierarchy);
/* Compute the polygon header size and use that to offset the body */
/* Compute the polygon header size and use that to offset the body */
unsigned header_size = panfrost_tiler_header_size(
width, height, t.hierarchy_mask, hierarchy);
unsigned header_size =
panfrost_tiler_header_size(width, height,
t.hierarchy_mask, hierarchy);
t.polygon_list_size = panfrost_tiler_full_size(
width, height, t.hierarchy_mask, hierarchy);
t.polygon_list_size =
panfrost_tiler_full_size(width, height, t.hierarchy_mask,
hierarchy);
if (vertex_count) {
t.polygon_list = panfrost_batch_get_polygon_list(batch,
header_size +
t.polygon_list_size);
if (vertex_count) {
t.polygon_list =
panfrost_batch_get_polygon_list(batch,
header_size +
t.polygon_list_size);
t.heap_start = device->tiler_heap->gpu;
t.heap_end = device->tiler_heap->gpu +
device->tiler_heap->size;
} else {
struct panfrost_bo *tiler_dummy;
t.heap_start = device->tiler_heap->gpu;
t.heap_end = device->tiler_heap->gpu + device->tiler_heap->size;
} else {
struct panfrost_bo *tiler_dummy;
tiler_dummy = panfrost_batch_get_tiler_dummy(batch);
header_size = MALI_MIDGARD_TILER_MINIMUM_HEADER_SIZE;
tiler_dummy = panfrost_batch_get_tiler_dummy(batch);
header_size = MALI_TILER_MINIMUM_HEADER_SIZE;
/* The tiler is disabled, so don't allow the tiler heap */
t.heap_start = tiler_dummy->gpu;
t.heap_end = t.heap_start;
/* The tiler is disabled, so don't allow the tiler heap */
t.heap_start = tiler_dummy->gpu;
t.heap_end = t.heap_start;
/* Use a dummy polygon list */
t.polygon_list = tiler_dummy->gpu;
/* Use a dummy polygon list */
t.polygon_list = tiler_dummy->gpu;
/* Disable the tiler */
if (hierarchy)
t.hierarchy_mask |= MALI_MIDGARD_TILER_DISABLED;
else {
t.hierarchy_mask = MALI_MIDGARD_TILER_USER;
t.polygon_list_size = MALI_MIDGARD_TILER_MINIMUM_HEADER_SIZE + 4;
/* Disable the tiler */
if (hierarchy)
t.hierarchy_mask |= MALI_TILER_DISABLED;
else {
t.hierarchy_mask = MALI_TILER_USER;
t.polygon_list_size = MALI_TILER_MINIMUM_HEADER_SIZE + 4;
/* We don't have a WRITE_VALUE job, so write the polygon list manually */
uint32_t *polygon_list_body = (uint32_t *) (tiler_dummy->cpu + header_size);
polygon_list_body[0] = 0xa0000000; /* TODO: Just that? */
/* We don't have a WRITE_VALUE job, so write the polygon list manually */
uint32_t *polygon_list_body = (uint32_t *) (tiler_dummy->cpu + header_size);
polygon_list_body[0] = 0xa0000000; /* TODO: Just that? */
}
}
t.polygon_list_body = t.polygon_list + header_size;
}
t.polygon_list_body =
t.polygon_list + header_size;
return t;
}
static void

View file

@ -347,8 +347,10 @@ panfrost_attach_mfbd(struct panfrost_batch *batch, unsigned vertex_count);
void
panfrost_attach_sfbd(struct panfrost_batch *batch, unsigned vertex_count);
struct midgard_tiler_descriptor
panfrost_emit_midg_tiler(struct panfrost_batch *batch, unsigned vertex_count);
void
panfrost_emit_midg_tiler(struct panfrost_batch *batch,
struct mali_midgard_tiler_packed *tp,
unsigned vertex_count);
mali_ptr
panfrost_fragment_job(struct panfrost_batch *batch, bool has_draws);

View file

@ -1102,7 +1102,7 @@ panfrost_batch_submit(struct panfrost_batch *batch, uint32_t out_sync)
}
mali_ptr polygon_list = panfrost_batch_get_polygon_list(batch,
MALI_TILER_MINIMUM_HEADER_SIZE);
MALI_MIDGARD_TILER_MINIMUM_HEADER_SIZE);
panfrost_scoreboard_initialize_tiler(&batch->pool, &batch->scoreboard, polygon_list);

View file

@ -516,7 +516,10 @@ panfrost_emit_mfbd(struct panfrost_batch *batch, unsigned vertex_count)
ls.wls_instances = MALI_LOCAL_STORAGE_NO_WORKGROUP_MEM;
}
mfbd.shared_memory = lsp;
mfbd.tiler = panfrost_emit_midg_tiler(batch, vertex_count);
struct mali_midgard_tiler_packed t;
panfrost_emit_midg_tiler(batch, &t, vertex_count);
mfbd.tiler = t;
}
return mfbd;

View file

@ -211,9 +211,12 @@ panfrost_emit_sfbd(struct panfrost_batch *batch, unsigned vertex_count)
.unk3 = 0x3,
},
.clear_flags = 0x1000,
.tiler = panfrost_emit_midg_tiler(batch, vertex_count),
};
struct mali_midgard_tiler_packed t;
panfrost_emit_midg_tiler(batch, &t, vertex_count);
framebuffer.tiler = t;
struct mali_local_storage_packed lsp;
pan_pack(&lsp, LOCAL_STORAGE, ls) {
ls.tls_size = shift;

View file

@ -561,56 +561,6 @@ struct mali_payload_fragment {
#define MALI_CLEAR_SLOW (1 << 28)
#define MALI_CLEAR_SLOW_STENCIL (1 << 31)
/* Configures hierarchical tiling on Midgard for both SFBD/MFBD (embedded
* within the larget framebuffer descriptor). Analogous to
* bifrost_tiler_heap_meta and bifrost_tiler_meta*/
/* See pan_tiler.c for derivation */
#define MALI_HIERARCHY_MASK ((1 << 9) - 1)
/* Flag disabling the tiler for clear-only jobs, with
hierarchical tiling */
#define MALI_TILER_DISABLED (1 << 12)
/* Flag selecting userspace-generated polygon list, for clear-only jobs without
* hierarhical tiling. */
#define MALI_TILER_USER 0xFFF
/* Absent any geometry, the minimum size of the polygon list header */
#define MALI_TILER_MINIMUM_HEADER_SIZE 0x200
struct midgard_tiler_descriptor {
/* Size of the entire polygon list; see pan_tiler.c for the
* computation. It's based on hierarchical tiling */
u32 polygon_list_size;
/* Name known from the replay workaround in the kernel. What exactly is
* flagged here is less known. We do that (tiler_hierarchy_mask & 0x1ff)
* specifies a mask of hierarchy weights, which explains some of the
* performance mysteries around setting it. We also see the bottom bit
* of tiler_flags set in the kernel, but no comment why.
*
* hierarchy_mask can have the TILER_DISABLED flag */
u16 hierarchy_mask;
u16 flags;
/* See mali_tiler.c for an explanation */
mali_ptr polygon_list;
mali_ptr polygon_list_body;
/* Names based on we see symmetry with replay jobs which name these
* explicitly */
mali_ptr heap_start; /* tiler heap_free_address */
mali_ptr heap_end;
/* Hierarchy weights. We know these are weights based on the kernel,
* but I've never seen them be anything other than zero */
u32 weights[8];
};
struct mali_sfbd_format {
/* 0x1 */
unsigned unk1 : 6;
@ -698,7 +648,8 @@ struct mali_single_framebuffer {
u32 zero6[7];
struct midgard_tiler_descriptor tiler;
struct mali_midgard_tiler_packed tiler;
struct mali_midgard_tiler_weights_packed tiler_weights;
/* More below this, maybe */
} __attribute__((packed));
@ -864,7 +815,10 @@ struct mali_framebuffer {
float clear_depth;
union {
struct midgard_tiler_descriptor tiler;
struct {
struct mali_midgard_tiler_packed tiler;
struct mali_midgard_tiler_weights_packed tiler_weights;
};
struct {
mali_ptr tiler_meta;
u32 zeros[16];

View file

@ -277,30 +277,21 @@ static const struct pandecode_flag_info sfbd_unk2_info [] = {
static void
pandecode_midgard_tiler_descriptor(
const struct midgard_tiler_descriptor *t,
const struct mali_midgard_tiler_packed *tp,
const struct mali_midgard_tiler_weights_packed *wp,
unsigned width,
unsigned height,
bool is_fragment,
bool has_hierarchy)
{
pandecode_log(".tiler = {\n");
pandecode_indent++;
pan_unpack(tp, MIDGARD_TILER, t);
DUMP_UNPACKED(MIDGARD_TILER, t, "Tiler:\n");
if (t->hierarchy_mask == MALI_TILER_DISABLED)
pandecode_prop("hierarchy_mask = MALI_TILER_DISABLED");
else
pandecode_prop("hierarchy_mask = 0x%" PRIx16, t->hierarchy_mask);
/* We know this name from the kernel, but we never see it nonzero */
if (t->flags)
pandecode_msg("XXX: unexpected tiler flags 0x%" PRIx16, t->flags);
MEMORY_PROP(t, polygon_list);
MEMORY_PROP_DIR(t, polygon_list);
/* The body is offset from the base of the polygon list */
//assert(t->polygon_list_body > t->polygon_list);
unsigned body_offset = t->polygon_list_body - t->polygon_list;
unsigned body_offset = t.polygon_list_body - t.polygon_list;
/* It needs to fit inside the reported size */
//assert(t->polygon_list_size >= body_offset);
@ -308,13 +299,13 @@ pandecode_midgard_tiler_descriptor(
/* Now that we've sanity checked, we'll try to calculate the sizes
* ourselves for comparison */
unsigned ref_header = panfrost_tiler_header_size(width, height, t->hierarchy_mask, has_hierarchy);
unsigned ref_size = panfrost_tiler_full_size(width, height, t->hierarchy_mask, has_hierarchy);
unsigned ref_header = panfrost_tiler_header_size(width, height, t.hierarchy_mask, has_hierarchy);
unsigned ref_size = panfrost_tiler_full_size(width, height, t.hierarchy_mask, has_hierarchy);
if (!((ref_header == body_offset) && (ref_size == t->polygon_list_size))) {
if (!((ref_header == body_offset) && (ref_size == t.polygon_list_size))) {
pandecode_msg("XXX: bad polygon list size (expected %d / 0x%x)\n",
ref_header, ref_size);
pandecode_prop("polygon_list_size = 0x%x", t->polygon_list_size);
pandecode_prop("polygon_list_size = 0x%x", t.polygon_list_size);
pandecode_msg("body offset %d\n", body_offset);
}
@ -322,14 +313,14 @@ pandecode_midgard_tiler_descriptor(
* identical to what we have in the BO. The exception is if tiling is
* disabled. */
MEMORY_PROP(t, heap_start);
assert(t->heap_end >= t->heap_start);
MEMORY_PROP_DIR(t, heap_start);
assert(t.heap_end >= t.heap_start);
unsigned heap_size = t->heap_end - t->heap_start;
unsigned heap_size = t.heap_end - t.heap_start;
/* Tiling is enabled with a special flag */
unsigned hierarchy_mask = t->hierarchy_mask & MALI_HIERARCHY_MASK;
unsigned tiler_flags = t->hierarchy_mask ^ hierarchy_mask;
unsigned hierarchy_mask = t.hierarchy_mask & MALI_MIDGARD_TILER_HIERARCHY_MASK;
unsigned tiler_flags = t.hierarchy_mask ^ hierarchy_mask;
bool tiling_enabled = hierarchy_mask;
@ -340,8 +331,8 @@ pandecode_midgard_tiler_descriptor(
} else {
/* When tiling is disabled, we should have that flag and no others */
if (tiler_flags != MALI_TILER_DISABLED) {
pandecode_msg("XXX: unexpected tiler flag %X, expected MALI_TILER_DISABLED\n",
if (tiler_flags != MALI_MIDGARD_TILER_DISABLED) {
pandecode_msg("XXX: unexpected tiler flag %X, expected MALI_MIDGARD_TILER_DISABLED\n",
tiler_flags);
}
@ -362,24 +353,20 @@ pandecode_midgard_tiler_descriptor(
/* We've never seen weights used in practice, but we know from the
* kernel these fields is there */
pan_unpack(wp, MIDGARD_TILER_WEIGHTS, w);
bool nonzero_weights = false;
for (unsigned w = 0; w < ARRAY_SIZE(t->weights); ++w) {
nonzero_weights |= t->weights[w] != 0x0;
}
nonzero_weights |= w.weight0 != 0x0;
nonzero_weights |= w.weight1 != 0x0;
nonzero_weights |= w.weight2 != 0x0;
nonzero_weights |= w.weight3 != 0x0;
nonzero_weights |= w.weight4 != 0x0;
nonzero_weights |= w.weight5 != 0x0;
nonzero_weights |= w.weight6 != 0x0;
nonzero_weights |= w.weight7 != 0x0;
if (nonzero_weights) {
pandecode_log(".weights = { ");
for (unsigned w = 0; w < ARRAY_SIZE(t->weights); ++w) {
pandecode_log_cont("%d, ", t->weights[w]);
}
pandecode_log("},");
}
pandecode_indent--;
pandecode_log("}\n");
if (nonzero_weights)
DUMP_UNPACKED(MIDGARD_TILER_WEIGHTS, w, "Tiler Weights:\n");
}
/* TODO: The Bifrost tiler is not understood at all yet */
@ -525,10 +512,11 @@ pandecode_sfbd(uint64_t gpu_va, int job_no, bool is_fragment, unsigned gpu_id)
pandecode_prop("clear_stencil = 0x%x", s->clear_stencil);
}
const struct midgard_tiler_descriptor t = s->tiler;
const struct mali_midgard_tiler_packed t = s->tiler;
const struct mali_midgard_tiler_weights_packed w = s->tiler_weights;
bool has_hierarchy = !(gpu_id == 0x0720 || gpu_id == 0x0820 || gpu_id == 0x0830);
pandecode_midgard_tiler_descriptor(&t, s->width + 1, s->height + 1, is_fragment, has_hierarchy);
pandecode_midgard_tiler_descriptor(&t, &w, s->width + 1, s->height + 1, is_fragment, has_hierarchy);
pandecode_indent--;
pandecode_log("};\n");
@ -858,8 +846,9 @@ pandecode_mfbd_bfr(uint64_t gpu_va, int job_no, bool is_fragment, bool is_comput
if (is_bifrost)
pandecode_bifrost_tiler_descriptor(fb);
else {
const struct midgard_tiler_descriptor t = fb->tiler;
pandecode_midgard_tiler_descriptor(&t, fb->width1 + 1, fb->height1 + 1, is_fragment, true);
const struct mali_midgard_tiler_packed t = fb->tiler;
const struct mali_midgard_tiler_weights_packed w = fb->tiler_weights;
pandecode_midgard_tiler_descriptor(&t, &w, fb->width1 + 1, fb->height1 + 1, is_fragment, true);
}
else
pandecode_msg("XXX: skipping compute MFBD, fixme\n");

View file

@ -573,4 +573,30 @@
<field name="TLS Base Pointer" size="64" start="2:0" type="address"/>
<field name="WLS Base Pointer" size="64" start="4:0" type="address"/>
</struct>
<struct name="Midgard Tiler">
<field name="Polygon List Size" size="32" start="0:0" type="uint" prefix="MALI_MIDGARD_TILER">
<value name="Minimum Header Size" value="512"/>
</field>
<field name="Hierarchy Mask" size="16" start="1:0" type="uint" prefix="MALI_MIDGARD_TILER">
<value name="Disabled" value="4096"/>
<value name="User" value="4095"/>
<value name="Hierarchy Mask" value="511"/>
</field>
<field name="Polygon List" size="64" start="2:0" type="address"/>
<field name="Polygon List Body" size="64" start="4:0" type="address"/>
<field name="Heap Start" size="64" start="6:0" type="address"/>
<field name="Heap End" size="64" start="8:0" type="address"/>
</struct>
<struct name="Midgard Tiler Weights">
<field name="Weight0" size="32" start="0:0" type="uint"/>
<field name="Weight1" size="32" start="1:0" type="uint"/>
<field name="Weight2" size="32" start="2:0" type="uint"/>
<field name="Weight3" size="32" start="3:0" type="uint"/>
<field name="Weight4" size="32" start="4:0" type="uint"/>
<field name="Weight5" size="32" start="5:0" type="uint"/>
<field name="Weight6" size="32" start="6:0" type="uint"/>
<field name="Weight7" size="32" start="7:0" type="uint"/>
</struct>
</panxml>