mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-25 11:20:49 +02:00
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:
parent
fb95729b69
commit
e855698ddd
8 changed files with 123 additions and 142 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue