panfrost: Rework format encoding on SFBD

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
This commit is contained in:
Tomeu Vizoso
2019-10-30 12:05:30 +01:00
parent e40d11ccb2
commit 9447a84f69
8 changed files with 213 additions and 93 deletions
+3 -1
View File
@@ -118,7 +118,9 @@ panfrost_emit_sfbd(struct panfrost_batch *batch, unsigned vertex_count)
.width = MALI_POSITIVE(width),
.height = MALI_POSITIVE(height),
.unknown2 = 0x1f,
.format = 0x30000000,
.format = {
.unk3 = 0x3,
},
.clear_flags = 0x1000,
.unknown_address_0 = panfrost_batch_get_scratchpad(batch)->gpu,
.tiler = panfrost_emit_midg_tiler(batch, vertex_count),
+22
View File
@@ -247,4 +247,26 @@ panfrost_find_format(const struct util_format_description *desc) {
return (enum mali_format) format;
}
void
panfrost_invert_swizzle(const unsigned char *in, unsigned char *out)
{
/* First, default to all zeroes to prevent uninitialized junk */
for (unsigned c = 0; c < 4; ++c)
out[c] = PIPE_SWIZZLE_0;
/* Now "do" what the swizzle says */
for (unsigned c = 0; c < 4; ++c) {
unsigned char i = in[c];
/* Who cares? */
assert(PIPE_SWIZZLE_X == 0);
if (i > PIPE_SWIZZLE_W)
continue;
/* Invert */
unsigned idx = i - PIPE_SWIZZLE_X;
out[idx] = PIPE_SWIZZLE_X + c;
}
}
@@ -37,6 +37,9 @@ panfrost_get_default_swizzle(unsigned components);
enum mali_format
panfrost_find_format(const struct util_format_description *desc);
void
panfrost_invert_swizzle(const unsigned char *in, unsigned char *out);
#endif
+3 -27
View File
@@ -29,30 +29,6 @@
#include "util/u_format.h"
static void
panfrost_invert_swizzle(const unsigned char *in, unsigned char *out)
{
/* First, default to all zeroes to prevent uninitialized junk */
for (unsigned c = 0; c < 4; ++c)
out[c] = PIPE_SWIZZLE_0;
/* Now "do" what the swizzle says */
for (unsigned c = 0; c < 4; ++c) {
unsigned char i = in[c];
/* Who cares? */
assert(PIPE_SWIZZLE_X == 0);
if (i > PIPE_SWIZZLE_W)
continue;
/* Invert */
unsigned idx = i - PIPE_SWIZZLE_X;
out[idx] = PIPE_SWIZZLE_X + c;
}
}
static struct mali_rt_format
panfrost_mfbd_format(struct pipe_surface *surf)
{
@@ -224,15 +200,15 @@ panfrost_mfbd_set_cbuf(
/* Now, we set the layout specific pieces */
if (rsrc->layout == PAN_LINEAR) {
rt->format.block = MALI_MFBD_BLOCK_LINEAR;
rt->format.block = MALI_BLOCK_LINEAR;
rt->framebuffer = base;
rt->framebuffer_stride = stride / 16;
} else if (rsrc->layout == PAN_TILED) {
rt->format.block = MALI_MFBD_BLOCK_TILED;
rt->format.block = MALI_BLOCK_TILED;
rt->framebuffer = base;
rt->framebuffer_stride = stride;
} else if (rsrc->layout == PAN_AFBC) {
rt->format.block = MALI_MFBD_BLOCK_AFBC;
rt->format.block = MALI_BLOCK_AFBC;
unsigned header_size = rsrc->slices[level].header_size;
+1 -3
View File
@@ -394,9 +394,7 @@ panfrost_resource_create_bo(struct panfrost_screen *screen, struct panfrost_reso
bool is_2d = res->depth0 == 1 && res->array_size == 1;
bool is_streaming = (res->usage != PIPE_USAGE_STREAM);
/* TODO: Reenable tiling on SFBD systems when we support rendering to
* tiled formats with SFBD */
bool should_tile = is_streaming && is_texture && is_2d && !screen->require_sfbd;
bool should_tile = is_streaming && is_texture && is_2d;
/* Depth/stencil can't be tiled, only linear or AFBC */
should_tile &= !(res->bind & PIPE_BIND_DEPTH_STENCIL);
+72 -15
View File
@@ -29,11 +29,56 @@
#include "util/u_format.h"
static unsigned
static struct mali_sfbd_format
panfrost_sfbd_format(struct pipe_surface *surf)
{
/* TODO */
return 0xb84e0281; /* RGB32, no MSAA */
/* Explode details on the format */
const struct util_format_description *desc =
util_format_description(surf->format);
/* The swizzle for rendering is inverted from texturing */
unsigned char swizzle[4];
panfrost_invert_swizzle(desc->swizzle, swizzle);
struct mali_sfbd_format fmt = {
.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)
fmt.unk2 |= MALI_SFBD_FORMAT_SRGB;
/* sRGB handled as a dedicated flag */
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) {
case PIPE_FORMAT_B5G6R5_UNORM:
fmt.unk1 = 0x5;
fmt.nr_channels = MALI_POSITIVE(2);
fmt.unk2 = 0x5;
break;
case PIPE_FORMAT_A4B4G4R4_UNORM:
case PIPE_FORMAT_B4G4R4A4_UNORM:
fmt.unk1 = 0x4;
fmt.nr_channels = MALI_POSITIVE(1);
fmt.unk2 = 0x5;
break;
default:
unreachable("Invalid format rendering");
}
return fmt;
}
static void
@@ -92,9 +137,14 @@ panfrost_sfbd_set_cbuf(
unsigned offset = rsrc->slices[level].offset;
signed stride = rsrc->slices[level].stride;
if (rsrc->layout == PAN_LINEAR) {
fb->framebuffer = rsrc->bo->gpu + offset;
fb->stride = stride;
fb->framebuffer = rsrc->bo->gpu + offset;
fb->stride = stride;
if (rsrc->layout == PAN_LINEAR)
fb->format.block = MALI_BLOCK_LINEAR;
else if (rsrc->layout == PAN_TILED) {
fb->format.block = MALI_BLOCK_TILED;
fb->stride *= 16;
} else {
fprintf(stderr, "Invalid render layout\n");
assert(0);
@@ -111,17 +161,22 @@ panfrost_sfbd_set_zsbuf(
unsigned level = surf->u.tex.level;
assert(surf->u.tex.first_layer == 0);
unsigned offset = rsrc->slices[level].offset;
if (rsrc->layout == PAN_LINEAR) {
/* TODO: What about format selection? */
/* TODO: Z/S stride selection? */
fb->depth_buffer = rsrc->bo->gpu + offset;
fb->depth_buffer_enable = MALI_DEPTH_STENCIL_ENABLE;
fb->depth_buffer = rsrc->bo->gpu + rsrc->slices[level].offset;
fb->depth_stride = rsrc->slices[level].stride;
fb->stencil_buffer = rsrc->bo->gpu + offset;
fb->stencil_buffer_enable = MALI_DEPTH_STENCIL_ENABLE;
fb->stencil_buffer = rsrc->bo->gpu + rsrc->slices[level].offset;
fb->stencil_stride = rsrc->slices[level].stride;
struct panfrost_resource *stencil = rsrc->separate_stencil;
if (stencil) {
struct panfrost_slice stencil_slice = stencil->slices[level];
fb->stencil_buffer = stencil->bo->gpu + stencil_slice.offset;
fb->stencil_stride = stencil_slice.stride;
}
} else {
fprintf(stderr, "Invalid render layout\n");
assert(0);
@@ -144,8 +199,10 @@ panfrost_sfbd_fragment(struct panfrost_batch *batch, bool has_draws)
if (batch->key.zsbuf)
panfrost_sfbd_set_zsbuf(&fb, batch->key.zsbuf);
if (batch->requirements & PAN_REQ_MSAA)
fb.format |= MALI_FRAMEBUFFER_MSAA_A | MALI_FRAMEBUFFER_MSAA_B;
if (batch->requirements & PAN_REQ_MSAA) {
fb.format.unk1 |= MALI_SFBD_FORMAT_MSAA_A;
fb.format.unk2 |= MALI_SFBD_FORMAT_MSAA_B;
}
struct pipe_surface *surf = batch->key.cbufs[0];
struct panfrost_resource *rsrc = pan_resource(surf->texture);
+38 -26
View File
@@ -75,15 +75,6 @@ enum mali_draw_mode {
#define MALI_CULL_FACE_FRONT (1 << 6)
#define MALI_CULL_FACE_BACK (1 << 7)
/* TODO: Might this actually be a finer bitfield? */
#define MALI_DEPTH_STENCIL_ENABLE 0x6400
#define DS_ENABLE(field) \
(field == MALI_DEPTH_STENCIL_ENABLE) \
? "MALI_DEPTH_STENCIL_ENABLE" \
: (field == 0) ? "0" \
: "0 /* XXX: Unknown, check hexdump */"
/* Used in stencil and depth tests */
enum mali_func {
@@ -1374,9 +1365,10 @@ struct mali_payload_fragment {
/* 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_FRAMEBUFFER_MSAA_8 (1 << 3)
#define MALI_FRAMEBUFFER_MSAA_A (1 << 4)
#define MALI_FRAMEBUFFER_MSAA_B (1 << 23)
#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 */
@@ -1426,6 +1418,32 @@ struct midgard_tiler_descriptor {
u32 weights[8];
};
enum mali_block_format {
MALI_BLOCK_TILED = 0x0,
MALI_BLOCK_UNKNOWN = 0x1,
MALI_BLOCK_LINEAR = 0x2,
MALI_BLOCK_AFBC = 0x3,
};
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;
};
struct mali_single_framebuffer {
u32 unknown1;
u32 unknown2;
@@ -1433,10 +1451,7 @@ struct mali_single_framebuffer {
u64 zero1;
u64 zero0;
/* Exact format is ironically not known, since EGL is finnicky with the
* blob. MSAA, colourspace, etc are configured here. */
u32 format;
struct mali_sfbd_format format;
u32 clear_flags;
u32 zero2;
@@ -1468,10 +1483,14 @@ struct mali_single_framebuffer {
* disabled. */
mali_ptr depth_buffer; // not SAME_VA
u64 depth_buffer_enable;
u32 depth_stride_zero : 4;
u32 depth_stride : 28;
u32 zero7;
mali_ptr stencil_buffer; // not SAME_VA
u64 stencil_buffer_enable;
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?
@@ -1506,13 +1525,6 @@ struct mali_compute_fbd {
#define MALI_MFBD_FORMAT_MSAA (1 << 1)
#define MALI_MFBD_FORMAT_SRGB (1 << 2)
enum mali_mfbd_block_format {
MALI_MFBD_BLOCK_TILED = 0x0,
MALI_MFBD_BLOCK_UNKNOWN = 0x1,
MALI_MFBD_BLOCK_LINEAR = 0x2,
MALI_MFBD_BLOCK_AFBC = 0x3,
};
struct mali_rt_format {
unsigned unk1 : 32;
unsigned unk2 : 3;
@@ -1520,7 +1532,7 @@ struct mali_rt_format {
unsigned nr_channels : 2; /* MALI_POSITIVE */
unsigned unk3 : 5;
enum mali_mfbd_block_format block : 2;
enum mali_block_format block : 2;
unsigned flags : 4;
unsigned swizzle : 12;
+71 -21
View File
@@ -42,6 +42,8 @@
int pandecode_jc(mali_ptr jc_gpu_va, bool bifrost);
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); \
@@ -238,15 +240,6 @@ static const struct pandecode_flag_info u4_flag_info[] = {
};
#undef FLAG_INFO
#define FLAG_INFO(flag) { MALI_FRAMEBUFFER_##flag, "MALI_FRAMEBUFFER_" #flag }
static const struct pandecode_flag_info fb_fmt_flag_info[] = {
FLAG_INFO(MSAA_A),
FLAG_INFO(MSAA_B),
FLAG_INFO(MSAA_8),
{}
};
#undef FLAG_INFO
#define FLAG_INFO(flag) { MALI_MFBD_FORMAT_##flag, "MALI_MFBD_FORMAT_" #flag }
static const struct pandecode_flag_info mfbd_fmt_flag_info[] = {
FLAG_INFO(MSAA),
@@ -292,6 +285,22 @@ static const struct pandecode_flag_info sampler_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
extern char *replace_fragment;
extern char *replace_vertex;
@@ -466,9 +475,9 @@ pandecode_wrap_mode(enum mali_wrap_mode op)
}
#undef DEFINE_CASE
#define DEFINE_CASE(name) case MALI_MFBD_BLOCK_## name: return "MALI_MFBD_BLOCK_" #name
#define DEFINE_CASE(name) case MALI_BLOCK_## name: return "MALI_BLOCK_" #name
static char *
pandecode_mfbd_block_format(enum mali_mfbd_block_format fmt)
pandecode_block_format(enum mali_block_format fmt)
{
switch (fmt) {
DEFINE_CASE(TILED);
@@ -633,6 +642,36 @@ struct pandecode_fbd {
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)",
MALI_NEGATIVE(format.nr_channels));
pandecode_log(".unk2 = ");
pandecode_log_decoded_flags(sfbd_unk2_info, format.unk2);
pandecode_log_cont(",\n");
pandecode_prop("block = %s", pandecode_block_format(format.block));
pandecode_prop("unk3 = 0x%" PRIx32, format.unk3);
pandecode_indent--;
pandecode_log("},\n");
}
static struct pandecode_fbd
pandecode_sfbd(uint64_t gpu_va, int job_no, bool is_fragment)
{
@@ -650,9 +689,7 @@ pandecode_sfbd(uint64_t gpu_va, int job_no, bool is_fragment)
pandecode_prop("unknown1 = 0x%" PRIx32, s->unknown1);
pandecode_prop("unknown2 = 0x%" PRIx32, s->unknown2);
pandecode_log(".format = ");
pandecode_log_decoded_flags(fb_fmt_flag_info, s->format);
pandecode_log_cont(",\n");
pandecode_sfbd_format(s->format);
info.width = s->width + 1;
info.height = s->height + 1;
@@ -675,14 +712,28 @@ pandecode_sfbd(uint64_t gpu_va, int job_no, bool is_fragment)
pandecode_log_decoded_flags(clear_flag_info, s->clear_flags);
pandecode_log_cont(",\n");
if (s->depth_buffer | s->depth_buffer_enable) {
if (s->depth_buffer) {
MEMORY_PROP(s, depth_buffer);
pandecode_prop("depth_buffer_enable = %s", DS_ENABLE(s->depth_buffer_enable));
pandecode_prop("depth_stride = %d", s->depth_stride);
}
if (s->stencil_buffer | s->stencil_buffer_enable) {
if (s->stencil_buffer) {
MEMORY_PROP(s, stencil_buffer);
pandecode_prop("stencil_buffer_enable = %s", DS_ENABLE(s->stencil_buffer_enable));
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) {
@@ -894,8 +945,7 @@ pandecode_rt_format(struct mali_rt_format format)
pandecode_prop("unk2 = 0x%" PRIx32, format.unk2);
pandecode_prop("unk3 = 0x%" PRIx32, format.unk3);
pandecode_prop("block = %s",
pandecode_mfbd_block_format(format.block));
pandecode_prop("block = %s", pandecode_block_format(format.block));
/* TODO: Map formats so we can check swizzles and print nicely */
pandecode_log("swizzle");
@@ -944,7 +994,7 @@ pandecode_render_target(uint64_t gpu_va, unsigned job_no, const struct bifrost_f
pandecode_rt_format(rt->format);
if (rt->format.block == MALI_MFBD_BLOCK_AFBC) {
if (rt->format.block == MALI_BLOCK_AFBC) {
pandecode_log(".afbc = {\n");
pandecode_indent++;