From: Tomeu Vizoso Date: Wed, 30 Oct 2019 11:05:30 +0000 (+0100) Subject: panfrost: Rework format encoding on SFBD X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9447a84f69c639cdd84fccec7e9447b88be35e30;p=mesa.git panfrost: Rework format encoding on SFBD Signed-off-by: Alyssa Rosenzweig Signed-off-by: Tomeu Vizoso Reviewed-by: Alyssa Rosenzweig --- diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 5334c686941..e8cedb96187 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -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), diff --git a/src/gallium/drivers/panfrost/pan_format.c b/src/gallium/drivers/panfrost/pan_format.c index f272e3a3716..2596b41feac 100644 --- a/src/gallium/drivers/panfrost/pan_format.c +++ b/src/gallium/drivers/panfrost/pan_format.c @@ -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; + } +} diff --git a/src/gallium/drivers/panfrost/pan_format.h b/src/gallium/drivers/panfrost/pan_format.h index a44d1d80994..4baac8a0e59 100644 --- a/src/gallium/drivers/panfrost/pan_format.h +++ b/src/gallium/drivers/panfrost/pan_format.h @@ -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 diff --git a/src/gallium/drivers/panfrost/pan_mfbd.c b/src/gallium/drivers/panfrost/pan_mfbd.c index b01f8289bf9..75f8887ec6d 100644 --- a/src/gallium/drivers/panfrost/pan_mfbd.c +++ b/src/gallium/drivers/panfrost/pan_mfbd.c @@ -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; diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index d0619a89882..08a3713a84c 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -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); diff --git a/src/gallium/drivers/panfrost/pan_sfbd.c b/src/gallium/drivers/panfrost/pan_sfbd.c index 882c9990a30..2be48e7155f 100644 --- a/src/gallium/drivers/panfrost/pan_sfbd.c +++ b/src/gallium/drivers/panfrost/pan_sfbd.c @@ -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 + 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); @@ -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); diff --git a/src/panfrost/include/panfrost-job.h b/src/panfrost/include/panfrost-job.h index dba8d3306b0..fb356e1e6d9 100644 --- a/src/panfrost/include/panfrost-job.h +++ b/src/panfrost/include/panfrost-job.h @@ -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; diff --git a/src/panfrost/pandecode/decode.c b/src/panfrost/pandecode/decode.c index 4d3d04248d0..7c1d681d018 100644 --- a/src/panfrost/pandecode/decode.c +++ b/src/panfrost/pandecode/decode.c @@ -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++;