panfrost: XML-ify the single target framebuffer 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-06 11:01:09 +02:00 committed by Alyssa Rosenzweig
parent e855698ddd
commit 95eb7d9a34
5 changed files with 310 additions and 380 deletions

View File

@ -741,7 +741,7 @@ panfrost_batch_reserve_framebuffer(struct panfrost_batch *batch)
if (!batch->framebuffer.gpu) { if (!batch->framebuffer.gpu) {
unsigned size = (dev->quirks & MIDGARD_SFBD) ? unsigned size = (dev->quirks & MIDGARD_SFBD) ?
sizeof(struct mali_single_framebuffer) : MALI_SINGLE_TARGET_FRAMEBUFFER_LENGTH :
sizeof(struct mali_framebuffer); sizeof(struct mali_framebuffer);
batch->framebuffer = panfrost_pool_alloc_aligned(&batch->pool, size, 64); batch->framebuffer = panfrost_pool_alloc_aligned(&batch->pool, size, 64);

View File

@ -28,8 +28,9 @@
#include "util/format/u_format.h" #include "util/format/u_format.h"
static struct mali_sfbd_format static void
panfrost_sfbd_format(struct pipe_surface *surf) panfrost_sfbd_format(struct pipe_surface *surf,
struct MALI_SINGLE_TARGET_FRAMEBUFFER_PARAMETERS *fb)
{ {
/* Explode details on the format */ /* Explode details on the format */
@ -41,90 +42,77 @@ panfrost_sfbd_format(struct pipe_surface *surf)
unsigned char swizzle[4]; unsigned char swizzle[4];
panfrost_invert_swizzle(desc->swizzle, swizzle); panfrost_invert_swizzle(desc->swizzle, swizzle);
struct mali_sfbd_format fmt = { fb->swizzle = panfrost_translate_swizzle_4(swizzle);
.unk1 = 0x1,
.swizzle = panfrost_translate_swizzle_4(swizzle),
.nr_channels = MALI_POSITIVE(desc->nr_channels),
.unk2 = 0x4,
.unk3 = 0xb,
};
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
fmt.unk2 |= MALI_SFBD_FORMAT_SRGB; fb->srgb = true;
if (util_format_is_unorm8(desc)) {
fb->internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_R8G8B8A8;
switch (desc->nr_channels) {
case 1:
fb->color_writeback_format = MALI_SFBD_COLOR_FORMAT_R8;
break;
case 2:
fb->color_writeback_format = MALI_SFBD_COLOR_FORMAT_R8G8;
break;
case 3:
fb->color_writeback_format = MALI_SFBD_COLOR_FORMAT_R8G8B8;
break;
case 4:
fb->color_writeback_format = MALI_SFBD_COLOR_FORMAT_R8G8B8A8;
break;
default:
unreachable("Invalid number of components");
}
/* If 8b RGB variant, we're good to go */
return;
}
/* sRGB handled as a dedicated flag */ /* sRGB handled as a dedicated flag */
enum pipe_format linearized = util_format_linear(surf->format); enum pipe_format linearized = util_format_linear(surf->format);
/* If RGB, we're good to go */
if (util_format_is_unorm8(desc))
return fmt;
switch (linearized) { switch (linearized) {
case PIPE_FORMAT_B5G6R5_UNORM: case PIPE_FORMAT_B5G6R5_UNORM:
fmt.unk1 = 0x5; fb->internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_R5G6B5A0;
fmt.nr_channels = MALI_POSITIVE(2); fb->color_writeback_format = MALI_SFBD_COLOR_FORMAT_R5G6B5;
fmt.unk2 = 0x5;
break; break;
case PIPE_FORMAT_A4B4G4R4_UNORM: case PIPE_FORMAT_A4B4G4R4_UNORM:
case PIPE_FORMAT_B4G4R4A4_UNORM: case PIPE_FORMAT_B4G4R4A4_UNORM:
case PIPE_FORMAT_R4G4B4A4_UNORM: case PIPE_FORMAT_R4G4B4A4_UNORM:
fmt.unk1 = 0x4; fb->internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_R4G4B4A4;
fmt.nr_channels = MALI_POSITIVE(1); fb->color_writeback_format = MALI_SFBD_COLOR_FORMAT_R4G4B4A4;
fmt.unk2 = 0x5;
break; break;
default: default:
unreachable("Invalid format rendering"); unreachable("Invalid format rendering");
} }
return fmt;
} }
static void static void
panfrost_sfbd_clear( panfrost_sfbd_clear(
struct panfrost_batch *batch, struct panfrost_batch *batch,
struct mali_single_framebuffer *sfbd) struct MALI_SINGLE_TARGET_FRAMEBUFFER_PARAMETERS *sfbd)
{ {
if (batch->clear & PIPE_CLEAR_COLOR) { if (batch->clear & PIPE_CLEAR_COLOR) {
sfbd->clear_color_1 = batch->clear_color[0][0]; sfbd->clear_color_0 = batch->clear_color[0][0];
sfbd->clear_color_2 = batch->clear_color[0][1]; sfbd->clear_color_1 = batch->clear_color[0][1];
sfbd->clear_color_3 = batch->clear_color[0][2]; sfbd->clear_color_2 = batch->clear_color[0][2];
sfbd->clear_color_4 = batch->clear_color[0][3]; sfbd->clear_color_3 = batch->clear_color[0][3];
} }
if (batch->clear & PIPE_CLEAR_DEPTH) { if (batch->clear & PIPE_CLEAR_DEPTH)
sfbd->clear_depth_1 = batch->clear_depth; sfbd->z_clear = batch->clear_depth;
sfbd->clear_depth_2 = batch->clear_depth;
sfbd->clear_depth_3 = batch->clear_depth;
sfbd->clear_depth_4 = batch->clear_depth;
}
if (batch->clear & PIPE_CLEAR_STENCIL) { if (batch->clear & PIPE_CLEAR_STENCIL)
sfbd->clear_stencil = batch->clear_stencil; sfbd->s_clear = batch->clear_stencil & 0xff;
}
/* Set flags based on what has been cleared, for the SFBD case */
/* XXX: What do these flags mean? */
int clear_flags = 0x101100;
if (!(batch->clear & ~(PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL))) {
/* On a tiler like this, it's fastest to clear all three buffers at once */
clear_flags |= MALI_CLEAR_FAST;
} else {
clear_flags |= MALI_CLEAR_SLOW;
if (batch->clear & PIPE_CLEAR_STENCIL)
clear_flags |= MALI_CLEAR_SLOW_STENCIL;
}
sfbd->clear_flags = clear_flags;
} }
static void static void
panfrost_sfbd_set_cbuf( panfrost_sfbd_set_cbuf(
struct mali_single_framebuffer *fb, struct MALI_SINGLE_TARGET_FRAMEBUFFER_PARAMETERS *fb,
struct pipe_surface *surf) struct pipe_surface *surf)
{ {
struct panfrost_resource *rsrc = pan_resource(surf->texture); struct panfrost_resource *rsrc = pan_resource(surf->texture);
@ -136,16 +124,17 @@ panfrost_sfbd_set_cbuf(
mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0); mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0);
fb->format = panfrost_sfbd_format(surf); panfrost_sfbd_format(surf, fb);
fb->framebuffer = base; fb->color_write_enable = true;
fb->stride = stride; fb->color_writeback.base = base;
fb->color_writeback.row_stride = stride;
if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR)
fb->format.block = MALI_BLOCK_FORMAT_LINEAR; fb->color_block_format = MALI_BLOCK_FORMAT_LINEAR;
else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) {
fb->format.block = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED; fb->color_block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED;
fb->stride *= 16; fb->color_writeback.row_stride *= 16;
} else { } else {
fprintf(stderr, "Invalid render modifier\n"); fprintf(stderr, "Invalid render modifier\n");
assert(0); assert(0);
@ -154,11 +143,10 @@ panfrost_sfbd_set_cbuf(
static void static void
panfrost_sfbd_set_zsbuf( panfrost_sfbd_set_zsbuf(
struct mali_single_framebuffer *fb, struct MALI_SINGLE_TARGET_FRAMEBUFFER_PARAMETERS *fb,
struct pipe_surface *surf) struct pipe_surface *surf)
{ {
struct panfrost_resource *rsrc = pan_resource(surf->texture); struct panfrost_resource *rsrc = pan_resource(surf->texture);
struct panfrost_context *ctx = pan_context(surf->context);
unsigned level = surf->u.tex.level; unsigned level = surf->u.tex.level;
assert(surf->u.tex.first_layer == 0); assert(surf->u.tex.first_layer == 0);
@ -166,59 +154,47 @@ panfrost_sfbd_set_zsbuf(
if (rsrc->modifier != DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) if (rsrc->modifier != DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED)
unreachable("Invalid render modifier."); unreachable("Invalid render modifier.");
fb->depth_buffer = rsrc->bo->gpu + rsrc->slices[level].offset; fb->zs_block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED;
fb->depth_stride = rsrc->slices[level].stride; fb->zs_writeback.base = rsrc->bo->gpu + rsrc->slices[level].offset;
fb->zs_writeback.row_stride = rsrc->slices[level].stride * 16;
/* No stencil? Job done. */ switch (surf->format) {
if (!ctx->depth_stencil || !ctx->depth_stencil->base.stencil[0].enabled) case PIPE_FORMAT_Z24_UNORM_S8_UINT:
return; fb->zs_format = MALI_ZS_FORMAT_D24S8;
break;
if (panfrost_is_z24s8_variant(surf->format)) { case PIPE_FORMAT_Z24X8_UNORM:
/* Stencil data is interleaved with depth */ fb->zs_format = MALI_ZS_FORMAT_D24X8;
fb->stencil_buffer = fb->depth_buffer; break;
fb->stencil_stride = fb->depth_stride; case PIPE_FORMAT_Z32_FLOAT:
} else if (surf->format == PIPE_FORMAT_Z32_FLOAT) { fb->zs_format = MALI_ZS_FORMAT_D32;
/* No stencil, nothing to do */ break;
} else if (surf->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) { case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
/* Stencil data in separate buffer */ fb->zs_format = MALI_ZS_FORMAT_D32_S8X24;
struct panfrost_resource *stencil = rsrc->separate_stencil; break;
struct panfrost_slice stencil_slice = stencil->slices[level]; default:
fb->stencil_buffer = stencil->bo->gpu + stencil_slice.offset;
fb->stencil_stride = stencil_slice.stride;
} else
unreachable("Unsupported depth/stencil format."); unreachable("Unsupported depth/stencil format.");
}
} }
static void
static struct mali_single_framebuffer panfrost_init_sfbd_params(struct panfrost_batch *batch,
panfrost_emit_sfbd(struct panfrost_batch *batch, unsigned vertex_count) struct MALI_SINGLE_TARGET_FRAMEBUFFER_PARAMETERS *sfbd)
{ {
struct panfrost_context *ctx = batch->ctx; sfbd->bound_max_x = batch->key.width - 1;
struct pipe_context *gallium = (struct pipe_context *) ctx; sfbd->bound_max_y = batch->key.height - 1;
struct panfrost_device *dev = pan_device(gallium->screen); sfbd->dithering_enable = true;
sfbd->clean_pixel_write_enable = true;
unsigned width = batch->key.width; sfbd->tie_break_rule = MALI_TIE_BREAK_RULE_MINUS_180_IN_0_OUT;
unsigned height = batch->key.height; }
static void
panfrost_emit_sfdb_local_storage(struct panfrost_batch *batch, void *sfbd,
unsigned vertex_count)
{
struct panfrost_device *dev = pan_device(batch->ctx->base.screen);
/* TODO: Why do we need to make the stack bigger than other platforms? */ /* TODO: Why do we need to make the stack bigger than other platforms? */
unsigned shift = panfrost_get_stack_shift(MAX2(batch->stack_size, 512)); unsigned shift = panfrost_get_stack_shift(MAX2(batch->stack_size, 512));
struct mali_single_framebuffer framebuffer = { pan_section_pack(sfbd, SINGLE_TARGET_FRAMEBUFFER, LOCAL_STORAGE, ls) {
.width = MALI_POSITIVE(width),
.height = MALI_POSITIVE(height),
.format = {
.unk3 = 0x3,
},
.clear_flags = 0x1000,
};
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; ls.tls_size = shift;
ls.wls_instances = MALI_LOCAL_STORAGE_NO_WORKGROUP_MEM; ls.wls_instances = MALI_LOCAL_STORAGE_NO_WORKGROUP_MEM;
ls.tls_base_pointer = ls.tls_base_pointer =
@ -227,18 +203,32 @@ panfrost_emit_sfbd(struct panfrost_batch *batch, unsigned vertex_count)
dev->thread_tls_alloc, dev->thread_tls_alloc,
dev->core_count)->gpu; dev->core_count)->gpu;
} }
framebuffer.shared_memory = lsp; }
return framebuffer; static void
panfrost_emit_sfdb_tiler(struct panfrost_batch *batch, void *sfbd,
unsigned vertex_count)
{
void *tiler = pan_section_ptr(sfbd, SINGLE_TARGET_FRAMEBUFFER, TILER);
panfrost_emit_midg_tiler(batch, tiler, vertex_count);
/* All weights set to 0, nothing to do here */
pan_section_pack(sfbd, SINGLE_TARGET_FRAMEBUFFER, PADDING_1, padding) {}
pan_section_pack(sfbd, SINGLE_TARGET_FRAMEBUFFER, TILER_WEIGHTS, w) {}
} }
void void
panfrost_attach_sfbd(struct panfrost_batch *batch, unsigned vertex_count) panfrost_attach_sfbd(struct panfrost_batch *batch, unsigned vertex_count)
{ {
struct mali_single_framebuffer sfbd = void *sfbd = batch->framebuffer.cpu;
panfrost_emit_sfbd(batch, vertex_count);
memcpy(batch->framebuffer.cpu, &sfbd, sizeof(sfbd)); panfrost_emit_sfdb_local_storage(batch, sfbd, vertex_count);
pan_section_pack(sfbd, SINGLE_TARGET_FRAMEBUFFER, PARAMETERS, params) {
panfrost_init_sfbd_params(batch, &params);
}
panfrost_emit_sfdb_tiler(batch, sfbd, vertex_count);
pan_section_pack(sfbd, SINGLE_TARGET_FRAMEBUFFER, PADDING_2, padding) {}
} }
/* Creates an SFBD for the FRAGMENT section of the bound framebuffer */ /* Creates an SFBD for the FRAGMENT section of the bound framebuffer */
@ -246,35 +236,46 @@ panfrost_attach_sfbd(struct panfrost_batch *batch, unsigned vertex_count)
mali_ptr mali_ptr
panfrost_sfbd_fragment(struct panfrost_batch *batch, bool has_draws) panfrost_sfbd_fragment(struct panfrost_batch *batch, bool has_draws)
{ {
struct mali_single_framebuffer fb = panfrost_emit_sfbd(batch, has_draws); struct panfrost_transfer t =
panfrost_pool_alloc_aligned(&batch->pool,
MALI_SINGLE_TARGET_FRAMEBUFFER_LENGTH,
64);
void *sfbd = t.cpu;
panfrost_sfbd_clear(batch, &fb); panfrost_emit_sfdb_local_storage(batch, sfbd, has_draws);
pan_section_pack(sfbd, SINGLE_TARGET_FRAMEBUFFER, PARAMETERS, params) {
panfrost_init_sfbd_params(batch, &params);
panfrost_sfbd_clear(batch, &params);
/* SFBD does not support MRT natively; sanity check */ /* SFBD does not support MRT natively; sanity check */
assert(batch->key.nr_cbufs <= 1); assert(batch->key.nr_cbufs <= 1);
if (batch->key.nr_cbufs) { if (batch->key.nr_cbufs) {
struct pipe_surface *surf = batch->key.cbufs[0]; struct pipe_surface *surf = batch->key.cbufs[0];
struct panfrost_resource *rsrc = pan_resource(surf->texture); struct panfrost_resource *rsrc = pan_resource(surf->texture);
struct panfrost_bo *bo = rsrc->bo; struct panfrost_bo *bo = rsrc->bo;
panfrost_sfbd_set_cbuf(&fb, surf); panfrost_sfbd_set_cbuf(&params, surf);
if (rsrc->checksummed) { if (rsrc->checksummed) {
unsigned level = surf->u.tex.level; unsigned level = surf->u.tex.level;
struct panfrost_slice *slice = &rsrc->slices[level]; struct panfrost_slice *slice = &rsrc->slices[level];
fb.checksum_stride = slice->checksum_stride; params.crc_buffer.row_stride = slice->checksum_stride;
fb.checksum = bo->gpu + slice->checksum_offset; params.crc_buffer.base = bo->gpu + slice->checksum_offset;
}
}
if (batch->key.zsbuf)
panfrost_sfbd_set_zsbuf(&params, batch->key.zsbuf);
if (batch->requirements & PAN_REQ_MSAA) {
/* Only 4x MSAA supported right now. */
params.sample_count = 4;
params.msaa = MALI_MSAA_MULTIPLE;
} }
} }
panfrost_emit_sfdb_tiler(batch, sfbd, has_draws);
pan_section_pack(sfbd, SINGLE_TARGET_FRAMEBUFFER, PADDING_2, padding) {}
if (batch->key.zsbuf) return t.gpu;
panfrost_sfbd_set_zsbuf(&fb, batch->key.zsbuf);
if (batch->requirements & PAN_REQ_MSAA) {
fb.format.unk1 |= MALI_SFBD_FORMAT_MSAA_A;
fb.format.unk2 |= MALI_SFBD_FORMAT_MSAA_B;
}
return panfrost_pool_upload_aligned(&batch->pool, &fb, sizeof(fb), 64);
} }

View File

@ -545,41 +545,6 @@ struct mali_payload_fragment {
mali_ptr framebuffer; mali_ptr framebuffer;
} __attribute__((packed)); } __attribute__((packed));
/* Single Framebuffer Descriptor */
/* Flags apply to format. With just MSAA_A and MSAA_B, the framebuffer is
* configured for 4x. With MSAA_8, it is configured for 8x. */
#define MALI_SFBD_FORMAT_MSAA_8 (1 << 3)
#define MALI_SFBD_FORMAT_MSAA_A (1 << 4)
#define MALI_SFBD_FORMAT_MSAA_B (1 << 4)
#define MALI_SFBD_FORMAT_SRGB (1 << 5)
/* Fast/slow based on whether all three buffers are cleared at once */
#define MALI_CLEAR_FAST (1 << 18)
#define MALI_CLEAR_SLOW (1 << 28)
#define MALI_CLEAR_SLOW_STENCIL (1 << 31)
struct mali_sfbd_format {
/* 0x1 */
unsigned unk1 : 6;
/* mali_channel_swizzle */
unsigned swizzle : 12;
/* MALI_POSITIVE */
unsigned nr_channels : 2;
/* 0x4 */
unsigned unk2 : 6;
enum mali_block_format block : 2;
/* 0xb */
unsigned unk3 : 4;
};
/* Configures multisampling on Bifrost fragment jobs */ /* Configures multisampling on Bifrost fragment jobs */
struct bifrost_multisampling { struct bifrost_multisampling {
@ -589,72 +554,6 @@ struct bifrost_multisampling {
u64 zero4; u64 zero4;
} __attribute__((packed)); } __attribute__((packed));
struct mali_single_framebuffer {
struct mali_local_storage_packed shared_memory;
struct mali_sfbd_format format;
u32 clear_flags;
u32 zero2;
/* Purposeful off-by-one in these fields should be accounted for by the
* MALI_DIMENSION macro */
u16 width;
u16 height;
u32 zero3[4];
mali_ptr checksum;
u32 checksum_stride;
u32 zero5;
/* By default, the framebuffer is upside down from OpenGL's
* perspective. Set framebuffer to the end and negate the stride to
* flip in the Y direction */
mali_ptr framebuffer;
int32_t stride;
u32 zero4;
/* Depth and stencil buffers are interleaved, it appears, as they are
* set to the same address in captures. Both fields set to zero if the
* buffer is not being cleared. Depending on GL_ENABLE magic, you might
* get a zero enable despite the buffer being present; that still is
* disabled. */
mali_ptr depth_buffer; // not SAME_VA
u32 depth_stride_zero : 4;
u32 depth_stride : 28;
u32 zero7;
mali_ptr stencil_buffer; // not SAME_VA
u32 stencil_stride_zero : 4;
u32 stencil_stride : 28;
u32 zero8;
u32 clear_color_1; // RGBA8888 from glClear, actually used by hardware
u32 clear_color_2; // always equal, but unclear function?
u32 clear_color_3; // always equal, but unclear function?
u32 clear_color_4; // always equal, but unclear function?
/* Set to zero if not cleared */
float clear_depth_1; // float32, ditto
float clear_depth_2; // float32, ditto
float clear_depth_3; // float32, ditto
float clear_depth_4; // float32, ditto
u32 clear_stencil; // Exactly as it appears in OpenGL
u32 zero6[7];
struct mali_midgard_tiler_packed tiler;
struct mali_midgard_tiler_weights_packed tiler_weights;
/* More below this, maybe */
} __attribute__((packed));
#define MALI_MFBD_FORMAT_SRGB (1 << 0) #define MALI_MFBD_FORMAT_SRGB (1 << 0)
struct mali_rt_format { struct mali_rt_format {

View File

@ -67,6 +67,12 @@ static void pandecode_swizzle(unsigned swizzle, enum mali_format format);
DUMP_UNPACKED(T, temp, __VA_ARGS__); \ DUMP_UNPACKED(T, temp, __VA_ARGS__); \
} }
#define DUMP_SECTION(A, S, cl, ...) { \
pan_section_unpack(cl, A, S, temp); \
pandecode_log(__VA_ARGS__); \
pan_section_print(pandecode_dump_stream, A, S, temp, (pandecode_indent + 1) * 2); \
}
#define MAP_ADDR(T, addr, cl) \ #define MAP_ADDR(T, addr, cl) \
const uint8_t *cl = 0; \ const uint8_t *cl = 0; \
{ \ { \
@ -211,15 +217,6 @@ pandecode_log_decoded_flags(const struct pandecode_flag_info *flag_info,
} }
} }
#define FLAG_INFO(flag) { MALI_CLEAR_##flag, "MALI_CLEAR_" #flag }
static const struct pandecode_flag_info clear_flag_info[] = {
FLAG_INFO(FAST),
FLAG_INFO(SLOW),
FLAG_INFO(SLOW_STENCIL),
{}
};
#undef FLAG_INFO
#define FLAG_INFO(flag) { MALI_MFBD_FORMAT_##flag, "MALI_MFBD_FORMAT_" #flag } #define FLAG_INFO(flag) { MALI_MFBD_FORMAT_##flag, "MALI_MFBD_FORMAT_" #flag }
static const struct pandecode_flag_info mfbd_fmt_flag_info[] = { static const struct pandecode_flag_info mfbd_fmt_flag_info[] = {
FLAG_INFO(SRGB), FLAG_INFO(SRGB),
@ -256,22 +253,6 @@ static const struct pandecode_flag_info mfbd_flag_info [] = {
}; };
#undef FLAG_INFO #undef FLAG_INFO
#define FLAG_INFO(flag) { MALI_SFBD_FORMAT_##flag, "MALI_SFBD_FORMAT_" #flag }
static const struct pandecode_flag_info sfbd_unk1_info [] = {
FLAG_INFO(MSAA_8),
FLAG_INFO(MSAA_A),
{}
};
#undef FLAG_INFO
#define FLAG_INFO(flag) { MALI_SFBD_FORMAT_##flag, "MALI_SFBD_FORMAT_" #flag }
static const struct pandecode_flag_info sfbd_unk2_info [] = {
FLAG_INFO(MSAA_B),
FLAG_INFO(SRGB),
{}
};
#undef FLAG_INFO
/* Midgard's tiler descriptor is embedded within the /* Midgard's tiler descriptor is embedded within the
* larger FBD */ * larger FBD */
@ -403,141 +384,38 @@ struct pandecode_fbd {
bool has_extra; bool has_extra;
}; };
static void
pandecode_sfbd_format(struct mali_sfbd_format format)
{
pandecode_log(".format = {\n");
pandecode_indent++;
pandecode_log(".unk1 = ");
pandecode_log_decoded_flags(sfbd_unk1_info, format.unk1);
pandecode_log_cont(",\n");
/* TODO: Map formats so we can check swizzles and print nicely */
pandecode_log("swizzle");
pandecode_swizzle(format.swizzle, MALI_RGBA8_UNORM);
pandecode_log_cont(",\n");
pandecode_prop("nr_channels = MALI_POSITIVE(%d)",
(format.nr_channels + 1));
pandecode_log(".unk2 = ");
pandecode_log_decoded_flags(sfbd_unk2_info, format.unk2);
pandecode_log_cont(",\n");
pandecode_prop("block = %s", mali_block_format_as_str(format.block));
pandecode_prop("unk3 = 0x%" PRIx32, format.unk3);
pandecode_indent--;
pandecode_log("},\n");
}
static struct pandecode_fbd static struct pandecode_fbd
pandecode_sfbd(uint64_t gpu_va, int job_no, bool is_fragment, unsigned gpu_id) pandecode_sfbd(uint64_t gpu_va, int job_no, bool is_fragment, unsigned gpu_id)
{ {
struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va); struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va);
const struct mali_single_framebuffer *PANDECODE_PTR_VAR(s, mem, (mali_ptr) gpu_va); const void *PANDECODE_PTR_VAR(s, mem, (mali_ptr) gpu_va);
struct pandecode_fbd info = { struct pandecode_fbd info = {
.has_extra = false, .has_extra = false,
.rt_count = 1 .rt_count = 1
}; };
pandecode_log("struct mali_single_framebuffer framebuffer_%"PRIx64"_%d = {\n", gpu_va, job_no); pandecode_log("Single-Target Framebuffer:\n");
pandecode_indent++; pandecode_indent++;
DUMP_CL(LOCAL_STORAGE, &s->shared_memory, "Local Storage:\n");
pandecode_sfbd_format(s->format);
info.width = s->width + 1; DUMP_SECTION(SINGLE_TARGET_FRAMEBUFFER, LOCAL_STORAGE, s, "Local Storage:\n");
info.height = s->height + 1; pan_section_unpack(s, SINGLE_TARGET_FRAMEBUFFER, PARAMETERS, p);
DUMP_UNPACKED(SINGLE_TARGET_FRAMEBUFFER_PARAMETERS, p, "Parameters:\n");
pandecode_prop("width = MALI_POSITIVE(%" PRId16 ")", info.width); const void *t = pan_section_ptr(s, SINGLE_TARGET_FRAMEBUFFER, TILER);
pandecode_prop("height = MALI_POSITIVE(%" PRId16 ")", info.height); const void *w = pan_section_ptr(s, SINGLE_TARGET_FRAMEBUFFER, TILER_WEIGHTS);
MEMORY_PROP(s, checksum);
if (s->checksum_stride)
pandecode_prop("checksum_stride = %d", s->checksum_stride);
MEMORY_PROP(s, framebuffer);
pandecode_prop("stride = %d", s->stride);
/* Earlier in the actual commandstream -- right before width -- but we
* delay to flow nicer */
pandecode_log(".clear_flags = ");
pandecode_log_decoded_flags(clear_flag_info, s->clear_flags);
pandecode_log_cont(",\n");
if (s->depth_buffer) {
MEMORY_PROP(s, depth_buffer);
pandecode_prop("depth_stride = %d", s->depth_stride);
}
if (s->stencil_buffer) {
MEMORY_PROP(s, stencil_buffer);
pandecode_prop("stencil_stride = %d", s->stencil_stride);
}
if (s->depth_stride_zero ||
s->stencil_stride_zero ||
s->zero7 || s->zero8) {
pandecode_msg("XXX: Depth/stencil zeros tripped\n");
pandecode_prop("depth_stride_zero = 0x%x",
s->depth_stride_zero);
pandecode_prop("stencil_stride_zero = 0x%x",
s->stencil_stride_zero);
pandecode_prop("zero7 = 0x%" PRIx32,
s->zero7);
pandecode_prop("zero8 = 0x%" PRIx32,
s->zero8);
}
if (s->clear_color_1 | s->clear_color_2 | s->clear_color_3 | s->clear_color_4) {
pandecode_prop("clear_color_1 = 0x%" PRIx32, s->clear_color_1);
pandecode_prop("clear_color_2 = 0x%" PRIx32, s->clear_color_2);
pandecode_prop("clear_color_3 = 0x%" PRIx32, s->clear_color_3);
pandecode_prop("clear_color_4 = 0x%" PRIx32, s->clear_color_4);
}
if (s->clear_depth_1 != 0 || s->clear_depth_2 != 0 || s->clear_depth_3 != 0 || s->clear_depth_4 != 0) {
pandecode_prop("clear_depth_1 = %f", s->clear_depth_1);
pandecode_prop("clear_depth_2 = %f", s->clear_depth_2);
pandecode_prop("clear_depth_3 = %f", s->clear_depth_3);
pandecode_prop("clear_depth_4 = %f", s->clear_depth_4);
}
if (s->clear_stencil) {
pandecode_prop("clear_stencil = 0x%x", s->clear_stencil);
}
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); bool has_hierarchy = !(gpu_id == 0x0720 || gpu_id == 0x0820 || gpu_id == 0x0830);
pandecode_midgard_tiler_descriptor(&t, &w, s->width + 1, s->height + 1, is_fragment, has_hierarchy); pandecode_midgard_tiler_descriptor(t, w, p.bound_max_x + 1, p.bound_max_y + 1, is_fragment, has_hierarchy);
pandecode_indent--; pandecode_indent--;
pandecode_log("};\n");
pandecode_prop("zero2 = 0x%" PRIx32, s->zero2); /* Dummy unpack of the padding section to make sure all words are 0.
pandecode_prop("zero4 = 0x%" PRIx32, s->zero4); * No need to call print here since the section is supposed to be empty.
pandecode_prop("zero5 = 0x%" PRIx32, s->zero5); */
pan_section_unpack(s, SINGLE_TARGET_FRAMEBUFFER, PADDING_1, padding1);
pandecode_log_cont(".zero3 = {"); pan_section_unpack(s, SINGLE_TARGET_FRAMEBUFFER, PADDING_2, padding2);
pandecode_log("\n");
for (int i = 0; i < sizeof(s->zero3) / sizeof(s->zero3[0]); ++i)
pandecode_log_cont("%X, ", s->zero3[i]);
pandecode_log_cont("},\n");
pandecode_log_cont(".zero6 = {");
for (int i = 0; i < sizeof(s->zero6) / sizeof(s->zero6[0]); ++i)
pandecode_log_cont("%X, ", s->zero6[i]);
pandecode_log_cont("},\n");
return info; return info;
} }

View File

@ -574,7 +574,7 @@
<field name="WLS Base Pointer" size="64" start="4:0" type="address"/> <field name="WLS Base Pointer" size="64" start="4:0" type="address"/>
</struct> </struct>
<struct name="Midgard Tiler"> <struct name="Midgard Tiler" size="10">
<field name="Polygon List Size" size="32" start="0:0" type="uint" prefix="MALI_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"/> <value name="Minimum Header Size" value="512"/>
</field> </field>
@ -599,4 +599,156 @@
<field name="Weight6" size="32" start="6:0" type="uint"/> <field name="Weight6" size="32" start="6:0" type="uint"/>
<field name="Weight7" size="32" start="7:0" type="uint"/> <field name="Weight7" size="32" start="7:0" type="uint"/>
</struct> </struct>
<enum name="Color Buffer Internal Format">
<value name="Raw Value" value="0"/>
<value name="R8G8B8A8" value="1"/>
<value name="R10G10B10A2" value="2"/>
<value name="R8G8B8A2" value="3"/>
<value name="R4G4B4A4" value="4"/>
<value name="R5G6B5A0" value="5"/>
<value name="R5G5B5A1" value="6"/>
<value name="RAW8" value="32"/>
<value name="RAW16" value="33"/>
<value name="RAW32" value="34"/>
<value name="RAW64" value="35"/>
<value name="RAW128" value="36"/>
</enum>
<enum name="SFBD Color Format">
<value name="4_32B_CHANNELS" value="0"/>
<value name="3_32B_CHANNELS" value="1"/>
<value name="2_32B_CHANNELS" value="2"/>
<value name="1_32B_CHANNEL" value="3"/>
<value name="4_16B_CHANNELS" value="4"/>
<value name="3_16B_CHANNELS" value="5"/>
<value name="2_16B_CHANNELS" value="6"/>
<value name="1_16B_CHANNEL" value="7"/>
<value name="R8" value="16"/>
<value name="R8G8" value="17"/>
<value name="R8G8B8" value="18"/>
<value name="R8G8B8A8" value="19"/>
<value name="R4G4B4A4" value="20"/>
<value name="R5G6B5" value="21"/>
<value name="R8G8B8_FROM_R8G8B8A2" value="22"/>
<value name="R10G10B10A2" value="24"/>
<value name="A2B10G10R10" value="25"/>
<value name="R5G5B5A1" value="28"/>
<value name="A1B5G5R5" value="29"/>
</enum>
<enum name="Downsampling Accumulation Mode">
<value name="Unsigned normalized integer" value="0"/>
<value name="Signed normalized integer" value="1"/>
</enum>
<enum name="Sample Layout">
<value name="Ordered 4x Grid" value="0"/>
<value name="Rotated 4x Grid" value="1"/>
<value name="D3D 8x Grid" value="2"/>
<value name="D3D 16x Grid" value="3"/>
</enum>
<enum name="ZS Format">
<value name="D16" value="1"/>
<value name="D24" value="2"/>
<value name="D24X8" value="4"/>
<value name="D24S8" value="5"/>
<value name="X8D24" value="6"/>
<value name="S8D24" value="7"/>
<value name="D32_X8X24" value="13"/>
<value name="D32" value="14"/>
<value name="D32_S8X24" value="15"/>
</enum>
<enum name="S Format">
<value name="S8" value="1"/>
<value name="S8X8" value="2"/>
<value name="S8X24" value="3"/>
<value name="X24S8" value="4"/>
<value name="X8S8" value="5"/>
<value name="X32_S8X24" value="6"/>
</enum>
<enum name="Tie-Break Rule">
<value name="0_IN_180_OUT" value="0"/>
<value name="0_OUT_180_IN" value="1"/>
<value name="MINUS_180_IN_0_OUT" value="2"/>
<value name="MINUS_180_OUT_0_IN" value="3"/>
<value name="90_IN_270_OUT" value="4"/>
<value name="90_OUT_270_IN" value="5"/>
<value name="MINUS_90_IN_90_OUT" value="6"/>
<value name="MINUS_90_OUT_90_IN" value="7"/>
</enum>
<struct name="RT Buffer">
<field name="Base" size="64" start="0:0" type="address"/>
<field name="Row Stride" size="32" start="2:0" type="uint"/>
<field name="Surface Stride" size="32" start="3:0" type="uint"/>
</struct>
<struct name="Single-Target Framebuffer Parameters" size="40">
<field name="Internal Format" size="3" start="0:0" default="Raw Value" type="Color Buffer Internal Format"/>
<field name="Sample Count" size="3" start="0:3" type="uint" default="1" modifier="log2"/>
<field name="Swizzle" size="12" start="0:6" type="uint"/>
<field name="Color Writeback Format" size="5" start="0:18" default="4_32B_CHANNELS" type="SFBD Color Format"/>
<field name="MSAA" size="2" start="0:23" default="Single" type="MSAA"/>
<field name="sRGB" size="1" start="0:25" type="bool"/>
<field name="Color Block Format" size="2" start="0:26" type="Block Format"/>
<field name="Dithering Enable" size="1" start="0:28" type="bool"/>
<field name="Clean Pixel Write Enable" size="1" start="0:29" type="bool"/>
<field name="Color Preload Enable" size="1" start="0:30" type="bool"/>
<field name="Color Write Enable" size="1" start="0:31" type="bool"/>
<field name="X Downsampling Scale" size="3" start="1:0" type="uint"/>
<field name="Y Downsampling Scale" size="3" start="1:3" type="uint"/>
<field name="Downsampling Accumulation Mode" size="2" start="1:6" type="Downsampling Accumulation Mode"/>
<field name="Sample Layout" size="2" start="1:8" type="Sample Layout"/>
<field name="Big Endian" size="1" start="1:10" type="bool"/>
<field name="Tie-Break Rule" size="3" start="1:11" type="Tie-Break Rule"/>
<field name="CRC Read Enable" size="1" start="1:14" type="bool"/>
<field name="CRC Write Enable" size="1" start="1:15" type="bool"/>
<field name="ZS Block Format" size="2" start="1:16" type="Block Format"/>
<field name="ZS Format" size="4" start="1:18" type="ZS Format" default="D24S8"/>
<field name="ZS Preload Enable" size="1" start="1:22" type="bool"/>
<field name="ZS Write Enable" size="1" start="1:23" type="bool"/>
<field name="S Block Format" size="2" start="1:24" type="Block Format"/>
<field name="S Format" size="4" start="1:26" type="S Format"/>
<field name="S Write Enable" size="1" start="1:31" type="bool"/>
<field name="Bound Min X" size="16" start="2:0" type="uint"/>
<field name="Bound Min Y" size="16" start="2:16" type="uint"/>
<field name="Bound Max X" size="16" start="3:0" type="uint"/>
<field name="Bound Max Y" size="16" start="3:16" type="uint"/>
<field name="DCD Offset" size="32" start="4:0" type="uint"/>
<field name="CRC Buffer" size="128" start="8:0" type="RT Buffer"/>
<field name="Color Writeback" size="128" start="12:0" type="RT Buffer"/>
<field name="ZS Writeback" size="128" start="16:0" type="RT Buffer"/>
<field name="S Writeback" size="128" start="20:0" type="RT Buffer"/>
<field name="Color Load Address" size="64" start="24:0" type="address"/>
<field name="Color Load Row Stride" size="32" start="26:0" type="uint"/>
<field name="Color Load Surface Stride" size="32" start="27:0" type="uint"/>
<field name="Clear Color 0" size="32" start="24:0" type="uint"/>
<field name="Clear Color 1" size="32" start="25:0" type="uint"/>
<field name="Clear Color 2" size="32" start="26:0" type="uint"/>
<field name="Clear Color 3" size="32" start="27:0" type="uint"/>
<field name="ZS Load Address" size="64" start="28:0" type="address"/>
<field name="ZS Load Row Stride" size="32" start="30:0" type="uint"/>
<field name="ZS Load Surface Stride" size="32" start="31:0" type="uint"/>
<field name="Z Clear" size="32" start="28:0" type="float"/>
<field name="S Clear" size="8" start="32:0" type="uint"/>
</struct>
<struct name="Single-Target Framebuffer Padding 1" size="6">
</struct>
<struct name="Single-Target Framebuffer Padding 2" size="8">
</struct>
<aggregate name="Single-Target Framebuffer" size="320">
<section name="Local Storage" offset="0" type="Local Storage"/>
<section name="Parameters" offset="32" type="Single-Target Framebuffer Parameters"/>
<section name="Tiler" offset="192" type="Midgard Tiler"/>
<section name="Padding 1" offset="232" type="Single-Target Framebuffer Padding 1"/>
<section name="Tiler Weights" offset="256" type="Midgard Tiler Weights"/>
<section name="Padding 2" offset="288" type="Single-Target Framebuffer Padding 2"/>
</aggregate>
</panxml> </panxml>