.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),
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;
+ }
+}
enum mali_format
panfrost_find_format(const struct util_format_description *desc);
+void
+panfrost_invert_swizzle(const unsigned char *in, unsigned char *out);
+
#endif
#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)
{
/* 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;
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);
#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
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);
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 + rsrc->slices[level].offset;
+ fb->stencil_stride = rsrc->slices[level].stride;
- fb->stencil_buffer = rsrc->bo->gpu + offset;
- fb->stencil_buffer_enable = MALI_DEPTH_STENCIL_ENABLE;
+ 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);
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);
#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 {
/* 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 */
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;
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;
* 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?
#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;
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;
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); \
};
#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),
};
#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;
}
#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);
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)
{
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;
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) {
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");
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++;