diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c index 7419c1d7e95..57abaa2d0d3 100644 --- a/src/gallium/drivers/panfrost/pan_job.c +++ b/src/gallium/drivers/panfrost/pan_job.c @@ -744,13 +744,13 @@ panfrost_batch_reserve_framebuffer(struct panfrost_batch *batch) if (!batch->framebuffer.gpu) { unsigned size = (dev->quirks & MIDGARD_SFBD) ? MALI_SINGLE_TARGET_FRAMEBUFFER_LENGTH : - sizeof(struct mali_framebuffer); + MALI_MULTI_TARGET_FRAMEBUFFER_LENGTH; batch->framebuffer = panfrost_pool_alloc_aligned(&batch->pool, size, 64); /* Tag the pointer */ if (!(dev->quirks & MIDGARD_SFBD)) - batch->framebuffer.gpu |= MALI_MFBD; + batch->framebuffer.gpu |= MALI_FBD_TAG_IS_MFBD; } return batch->framebuffer.gpu; diff --git a/src/gallium/drivers/panfrost/pan_mfbd.c b/src/gallium/drivers/panfrost/pan_mfbd.c index 5420916d8df..1e80b579960 100644 --- a/src/gallium/drivers/panfrost/pan_mfbd.c +++ b/src/gallium/drivers/panfrost/pan_mfbd.c @@ -28,8 +28,38 @@ #include "pan_util.h" #include "panfrost-quirks.h" -static struct mali_rt_format -panfrost_mfbd_format(struct pipe_surface *surf) + +static bool +panfrost_mfbd_has_zs_crc_ext(struct panfrost_batch *batch) +{ + if (batch->key.nr_cbufs == 1) { + struct pipe_surface *surf = batch->key.cbufs[0]; + struct panfrost_resource *rsrc = pan_resource(surf->texture); + + if (rsrc->checksummed) + return true; + } + + if (batch->key.zsbuf && + ((batch->clear | batch->draws) & PIPE_CLEAR_DEPTHSTENCIL)) + return true; + + return false; +} + +static unsigned +panfrost_mfbd_size(struct panfrost_batch *batch) +{ + unsigned rt_count = MAX2(batch->key.nr_cbufs, 1); + + return MALI_MULTI_TARGET_FRAMEBUFFER_LENGTH + + (panfrost_mfbd_has_zs_crc_ext(batch) * MALI_ZS_CRC_EXTENSION_LENGTH) + + (rt_count * MALI_RENDER_TARGET_LENGTH); +} + +static void +panfrost_mfbd_rt_init_format(struct pipe_surface *surf, + struct MALI_RENDER_TARGET *rt) { /* Explode details on the format */ @@ -41,68 +71,74 @@ panfrost_mfbd_format(struct pipe_surface *surf) unsigned char swizzle[4]; panfrost_invert_swizzle(desc->swizzle, swizzle); + rt->swizzle = panfrost_translate_swizzle_4(swizzle); + /* Fill in accordingly, defaulting to 8-bit UNORM */ - struct mali_rt_format fmt = { - .unk1 = 0x4000000, - .unk2 = 0x1, - .nr_channels = MALI_POSITIVE(desc->nr_channels), - .unk3 = 0x4, - .flags = 0x2, - .swizzle = panfrost_translate_swizzle_4(swizzle), - .no_preload = true - }; - if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) - fmt.flags |= MALI_MFBD_FORMAT_SRGB; + rt->srgb = true; /* 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; + if (util_format_is_unorm8(desc)) { + rt->internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_R8G8B8A8; + switch (desc->nr_channels) { + case 1: + rt->writeback_format = MALI_MFBD_COLOR_FORMAT_R8; + break; + case 2: + rt->writeback_format = MALI_MFBD_COLOR_FORMAT_R8G8; + break; + case 3: + rt->writeback_format = MALI_MFBD_COLOR_FORMAT_R8G8B8; + break; + case 4: + rt->writeback_format = MALI_MFBD_COLOR_FORMAT_R8G8B8A8; + break; + default: + unreachable("Invalid number of channels"); + } + + /* If RGB, we're good to go */ + return; + } /* Set flags for alternative formats */ switch (linearized) { case PIPE_FORMAT_B5G6R5_UNORM: - fmt.unk1 = 0x14000000; - fmt.nr_channels = MALI_POSITIVE(2); - fmt.unk3 |= 0x1; + rt->internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_R5G6B5A0; + rt->writeback_format = MALI_MFBD_COLOR_FORMAT_R5G6B5; break; case PIPE_FORMAT_A4B4G4R4_UNORM: case PIPE_FORMAT_B4G4R4A4_UNORM: case PIPE_FORMAT_R4G4B4A4_UNORM: - fmt.unk1 = 0x10000000; - fmt.unk3 = 0x5; - fmt.nr_channels = MALI_POSITIVE(1); + rt->internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_R4G4B4A4; + rt->writeback_format = MALI_MFBD_COLOR_FORMAT_R4G4B4A4; break; case PIPE_FORMAT_R10G10B10A2_UNORM: case PIPE_FORMAT_B10G10R10A2_UNORM: case PIPE_FORMAT_R10G10B10X2_UNORM: case PIPE_FORMAT_B10G10R10X2_UNORM: - fmt.unk1 = 0x08000000; - fmt.unk3 = 0x6; - fmt.nr_channels = MALI_POSITIVE(1); + rt->internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_R10G10B10A2; + rt->writeback_format = MALI_MFBD_COLOR_FORMAT_R10G10B10A2; break; case PIPE_FORMAT_B5G5R5A1_UNORM: case PIPE_FORMAT_R5G5B5A1_UNORM: case PIPE_FORMAT_B5G5R5X1_UNORM: - fmt.unk1 = 0x18000000; - fmt.unk3 = 0x7; - fmt.nr_channels = MALI_POSITIVE(2); + rt->internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_R5G5B5A1; + rt->writeback_format = MALI_MFBD_COLOR_FORMAT_R5G5B5A1; break; /* Generic 8-bit */ case PIPE_FORMAT_R8_UINT: case PIPE_FORMAT_R8_SINT: - fmt.unk1 = 0x80000000; - fmt.unk3 = 0x0; - fmt.nr_channels = MALI_POSITIVE(1); + rt->internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_RAW8; + rt->writeback_format = MALI_MFBD_COLOR_FORMAT_RAW8; break; /* Generic 32-bit */ @@ -116,9 +152,8 @@ panfrost_mfbd_format(struct pipe_surface *surf) case PIPE_FORMAT_R32_UINT: case PIPE_FORMAT_R32_SINT: case PIPE_FORMAT_R10G10B10A2_UINT: - fmt.unk1 = 0x88000000; - fmt.unk3 = 0x0; - fmt.nr_channels = MALI_POSITIVE(4); + rt->internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_RAW32; + rt->writeback_format = MALI_MFBD_COLOR_FORMAT_RAW32; break; /* Generic 16-bit */ @@ -127,9 +162,8 @@ panfrost_mfbd_format(struct pipe_surface *surf) case PIPE_FORMAT_R16_FLOAT: case PIPE_FORMAT_R16_UINT: case PIPE_FORMAT_R16_SINT: - fmt.unk1 = 0x84000000; - fmt.unk3 = 0x0; - fmt.nr_channels = MALI_POSITIVE(2); + rt->internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_RAW16; + rt->writeback_format = MALI_MFBD_COLOR_FORMAT_RAW16; break; /* Generic 64-bit */ @@ -139,73 +173,30 @@ panfrost_mfbd_format(struct pipe_surface *surf) case PIPE_FORMAT_R16G16B16A16_FLOAT: case PIPE_FORMAT_R16G16B16A16_SINT: case PIPE_FORMAT_R16G16B16A16_UINT: - fmt.unk1 = 0x8c000000; - fmt.unk3 = 0x1; - fmt.nr_channels = MALI_POSITIVE(2); + rt->internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_RAW64; + rt->writeback_format = MALI_MFBD_COLOR_FORMAT_RAW64; break; /* Generic 128-bit */ case PIPE_FORMAT_R32G32B32A32_FLOAT: case PIPE_FORMAT_R32G32B32A32_SINT: case PIPE_FORMAT_R32G32B32A32_UINT: - fmt.unk1 = 0x90000000; - fmt.unk3 = 0x1; - fmt.nr_channels = MALI_POSITIVE(4); + rt->internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_RAW128; + rt->writeback_format = MALI_MFBD_COLOR_FORMAT_RAW128; break; default: unreachable("Invalid format rendering"); } - - return fmt; -} - - -static void -panfrost_mfbd_clear( - struct panfrost_batch *batch, - struct mali_framebuffer *fb, - struct mali_framebuffer_extra *fbx, - struct mali_render_target *rts, - unsigned rt_count) -{ - struct panfrost_context *ctx = batch->ctx; - struct pipe_context *gallium = (struct pipe_context *) ctx; - struct panfrost_device *dev = pan_device(gallium->screen); - - for (unsigned i = 0; i < rt_count; ++i) { - if (!(batch->clear & (PIPE_CLEAR_COLOR0 << i))) - continue; - - rts[i].clear_color_1 = batch->clear_color[i][0]; - rts[i].clear_color_2 = batch->clear_color[i][1]; - rts[i].clear_color_3 = batch->clear_color[i][2]; - rts[i].clear_color_4 = batch->clear_color[i][3]; - } - - if (batch->clear & PIPE_CLEAR_DEPTH) { - fb->clear_depth = batch->clear_depth; - } - - if (batch->clear & PIPE_CLEAR_STENCIL) { - fb->clear_stencil = batch->clear_stencil; - } - - if (dev->quirks & IS_BIFROST) { - fbx->clear_color_1 = batch->clear_color[0][0]; - fbx->clear_color_2 = 0xc0000000 | (fbx->clear_color_1 & 0xffff); /* WTF? */ - } } static void -panfrost_mfbd_set_cbuf( - struct mali_render_target *rt, - struct pipe_surface *surf) +panfrost_mfbd_rt_set_buf(struct pipe_surface *surf, + struct MALI_RENDER_TARGET *rt) { - struct panfrost_resource *rsrc = pan_resource(surf->texture); struct panfrost_device *dev = pan_device(surf->context->screen); - bool is_bifrost = dev->quirks & IS_BIFROST; - + unsigned version = dev->gpu_id >> 12; + struct panfrost_resource *rsrc = pan_resource(surf->texture); unsigned level = surf->u.tex.level; unsigned first_layer = surf->u.tex.first_layer; assert(surf->u.tex.last_layer == first_layer); @@ -215,210 +206,239 @@ panfrost_mfbd_set_cbuf( unsigned nr_samples = surf->texture->nr_samples; unsigned layer_stride = (nr_samples > 1) ? rsrc->slices[level].size0 : 0; - mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0); - rt->format = panfrost_mfbd_format(surf); - if (layer_stride) - rt->format.msaa = MALI_MSAA_LAYERED; + rt->writeback_msaa = MALI_MSAA_LAYERED; else if (surf->nr_samples) - rt->format.msaa = MALI_MSAA_AVERAGE; + rt->writeback_msaa = MALI_MSAA_AVERAGE; else - rt->format.msaa = MALI_MSAA_SINGLE; + rt->writeback_msaa = MALI_MSAA_SINGLE; - /* Now, we set the modifier specific pieces */ + panfrost_mfbd_rt_init_format(surf, rt); if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) { - if (is_bifrost) { - rt->format.unk4 = 0x1; - } else { - rt->format.block = MALI_BLOCK_FORMAT_LINEAR; - } + if (version >= 7) + rt->writeback_block_format_v7 = MALI_BLOCK_FORMAT_V7_LINEAR; + else + rt->writeback_block_format = MALI_BLOCK_FORMAT_LINEAR; - rt->framebuffer = base; - rt->framebuffer_stride = stride / 16; - rt->layer_stride = layer_stride; + rt->writeback_base = base; + rt->writeback_row_stride = stride; + rt->writeback_surface_stride = layer_stride; } else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { - if (is_bifrost) { - rt->format.unk3 |= 0x8; - } else { - rt->format.block = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED; - } + if (version >= 7) + rt->writeback_block_format_v7 = MALI_BLOCK_FORMAT_V7_TILED_U_INTERLEAVED; + else + rt->writeback_block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED; - rt->framebuffer = base; - rt->framebuffer_stride = stride; - rt->layer_stride = layer_stride; + rt->writeback_base = base; + rt->writeback_row_stride = stride * 16; + rt->writeback_surface_stride = layer_stride; } else if (drm_is_afbc(rsrc->modifier)) { - rt->format.block = MALI_BLOCK_FORMAT_AFBC; + if (version >= 7) + rt->writeback_block_format = MALI_BLOCK_FORMAT_V7_AFBC; + else + rt->writeback_block_format = MALI_BLOCK_FORMAT_AFBC; unsigned header_size = rsrc->slices[level].header_size; - rt->framebuffer = base + header_size; - rt->layer_stride = layer_stride; - rt->afbc.metadata = base; - rt->afbc.stride = 0; - rt->afbc.flags = MALI_AFBC_FLAGS; + rt->afbc_header = base; + rt->afbc_chunk_size = 9; + rt->afbc_sparse = true; + rt->afbc_body = base + header_size; + rt->writeback_surface_stride = layer_stride; if (rsrc->modifier & AFBC_FORMAT_MOD_YTR) - rt->afbc.flags |= MALI_AFBC_YTR; + rt->afbc_yuv_transform_enable = true; /* TODO: The blob sets this to something nonzero, but it's not * clear what/how to calculate/if it matters */ - rt->framebuffer_stride = 0; + rt->afbc_body_size = 0; } else { unreachable("Invalid mod"); } } static void -panfrost_mfbd_set_zsbuf( - struct mali_framebuffer *fb, - struct mali_framebuffer_extra *fbx, - struct pipe_surface *surf) +panfrost_mfbd_emit_rt(struct panfrost_batch *batch, + void *rtp, struct pipe_surface *surf, + unsigned rt_offset, unsigned rt_idx) { - struct panfrost_device *dev = pan_device(surf->context->screen); - bool is_bifrost = dev->quirks & IS_BIFROST; - struct panfrost_resource *rsrc = pan_resource(surf->texture); + struct panfrost_device *dev = pan_device(batch->ctx->base.screen); + unsigned version = dev->gpu_id >> 12; - unsigned nr_samples = surf->texture->nr_samples; - nr_samples = MAX2(nr_samples, 1); + pan_pack(rtp, RENDER_TARGET, rt) { + rt.clean_pixel_write_enable = true; + if (surf) { + rt.write_enable = true; + rt.dithering_enable = true; + rt.internal_buffer_offset = rt_offset; + panfrost_mfbd_rt_set_buf(surf, &rt); + } else { + rt.internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_R8G8B8A8; + rt.internal_buffer_offset = rt_offset; + if (version >= 7) { + rt.writeback_block_format_v7 = MALI_BLOCK_FORMAT_V7_TILED_U_INTERLEAVED; + rt.dithering_enable = true; + } + } - fbx->zs_samples = MALI_POSITIVE(nr_samples); + if (batch->clear & (PIPE_CLEAR_COLOR0 << rt_idx)) { + rt.clear_color_0 = batch->clear_color[rt_idx][0]; + rt.clear_color_1 = batch->clear_color[rt_idx][1]; + rt.clear_color_2 = batch->clear_color[rt_idx][2]; + rt.clear_color_3 = batch->clear_color[rt_idx][3]; + } + } +} - unsigned level = surf->u.tex.level; - unsigned first_layer = surf->u.tex.first_layer; - assert(surf->u.tex.last_layer == first_layer); +static enum mali_z_internal_format +get_z_internal_format(struct panfrost_batch *batch) +{ + struct pipe_surface *zs_surf = batch->key.zsbuf; + + /* Default to 24 bit depth if there's no surface. */ + if (!zs_surf || !((batch->clear | batch->draws) & PIPE_CLEAR_DEPTHSTENCIL)) + return MALI_Z_INTERNAL_FORMAT_D24; + + return panfrost_get_z_internal_format(zs_surf->format); +} + +static void +panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch, + struct MALI_ZS_CRC_EXTENSION *ext) +{ + struct panfrost_device *dev = pan_device(batch->ctx->base.screen); + unsigned version = dev->gpu_id >> 12; + + /* Checksumming only works with a single render target */ + if (batch->key.nr_cbufs == 1) { + struct pipe_surface *c_surf = batch->key.cbufs[0]; + struct panfrost_resource *rsrc = pan_resource(c_surf->texture); + + if (rsrc->checksummed) { + unsigned level = c_surf->u.tex.level; + struct panfrost_slice *slice = &rsrc->slices[level]; + + ext->crc_row_stride = slice->checksum_stride; + if (slice->checksum_bo) + ext->crc_base = slice->checksum_bo->gpu; + else + ext->crc_base = rsrc->bo->gpu + slice->checksum_offset; + + if ((batch->clear & PIPE_CLEAR_COLOR0) && version >= 7) { + ext->crc_clear_color = batch->clear_color[0][0] | + 0xc000000000000000 | + ((uint64_t)batch->clear_color[0][0] & 0xffff) << 32; + } + } + } + + struct pipe_surface *zs_surf = batch->key.zsbuf; + + if (!((batch->clear | batch->draws) & PIPE_CLEAR_DEPTHSTENCIL)) + zs_surf = NULL; + + if (!zs_surf) + return; + + struct panfrost_resource *rsrc = pan_resource(zs_surf->texture); + unsigned nr_samples = MAX2(zs_surf->texture->nr_samples, 1); + unsigned level = zs_surf->u.tex.level; + unsigned first_layer = zs_surf->u.tex.first_layer; + assert(zs_surf->u.tex.last_layer == first_layer); mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0); + ext->zs_msaa = nr_samples > 1 ? MALI_MSAA_LAYERED : MALI_MSAA_SINGLE; + if (drm_is_afbc(rsrc->modifier)) { /* The only Z/S format we can compress is Z24S8 or variants * thereof (handled by the gallium frontend) */ - assert(panfrost_is_z24s8_variant(surf->format)); + assert(panfrost_is_z24s8_variant(zs_surf->format)); unsigned header_size = rsrc->slices[level].header_size; - fb->mfbd_flags |= MALI_MFBD_EXTRA | MALI_MFBD_DEPTH_WRITE; + ext->zs_write_format = MALI_ZS_FORMAT_D24S8; + if (version >= 7) + ext->zs_block_format_v7 = MALI_BLOCK_FORMAT_V7_AFBC; + else + ext->zs_block_format = MALI_BLOCK_FORMAT_AFBC; - fbx->flags_hi |= MALI_EXTRA_PRESENT; - fbx->flags_lo |= MALI_EXTRA_ZS | 0x1; /* unknown */ - fbx->zs_block = MALI_BLOCK_FORMAT_AFBC; - - fbx->ds_afbc.depth_stencil = base + header_size; - fbx->ds_afbc.depth_stencil_afbc_metadata = base; - fbx->ds_afbc.depth_stencil_afbc_stride = 0; - - fbx->ds_afbc.flags = MALI_AFBC_FLAGS; - fbx->ds_afbc.padding = 0x1000; + ext->zs_afbc_header = base; + ext->zs_afbc_body = base + header_size; + ext->zs_afbc_body_size = 0x1000; + ext->zs_afbc_chunk_size = 9; + ext->zs_afbc_sparse = true; } else { - assert(rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED || rsrc->modifier == DRM_FORMAT_MOD_LINEAR); + assert(rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED || + rsrc->modifier == DRM_FORMAT_MOD_LINEAR); /* TODO: Z32F(S8) support, which is always linear */ int stride = rsrc->slices[level].stride; unsigned layer_stride = (nr_samples > 1) ? rsrc->slices[level].size0 : 0; - fb->mfbd_flags |= MALI_MFBD_EXTRA | MALI_MFBD_DEPTH_WRITE; - fbx->flags_hi |= MALI_EXTRA_PRESENT; - fbx->flags_lo |= MALI_EXTRA_ZS; - - fbx->ds_linear.depth = base; + ext->zs_writeback_base = base; + ext->zs_writeback_row_stride = stride; + ext->zs_writeback_surface_stride = layer_stride; if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) { - fbx->zs_block = MALI_BLOCK_FORMAT_LINEAR; - fbx->ds_linear.depth_stride = stride / 16; - fbx->ds_linear.depth_layer_stride = layer_stride; + if (version >= 7) + ext->zs_block_format_v7 = MALI_BLOCK_FORMAT_V7_LINEAR; + else + ext->zs_block_format = MALI_BLOCK_FORMAT_LINEAR; } else { - if (is_bifrost) { - /* XXX: Bifrost fields are different here */ - fbx->zs_block = 1; - fbx->flags_hi |= 0x440; - fbx->flags_lo |= 0x1; - } else { - fbx->zs_block = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED; - } - - fbx->ds_linear.depth_stride = stride; - fbx->ds_linear.depth_layer_stride = layer_stride; + ext->zs_writeback_row_stride *= 16; + if (version >= 7) + ext->zs_block_format_v7 = MALI_BLOCK_FORMAT_V7_TILED_U_INTERLEAVED; + else + ext->zs_block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED; } - if (panfrost_is_z24s8_variant(surf->format)) { - fbx->flags_lo |= 0x1; - } else if (surf->format == PIPE_FORMAT_Z32_FLOAT) { - fbx->flags_lo |= 0xA; - fb->mfbd_flags ^= 0x100; - fb->mfbd_flags |= 0x200; - } else if (surf->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) { - fbx->flags_hi |= 0x40; - fbx->flags_lo |= 0xA; - fb->mfbd_flags ^= 0x100; - fb->mfbd_flags |= 0x201; + switch (zs_surf->format) { + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + ext->zs_write_format = MALI_ZS_FORMAT_D24S8; + break; + case PIPE_FORMAT_Z24X8_UNORM: + ext->zs_write_format = MALI_ZS_FORMAT_D24X8; + break; + case PIPE_FORMAT_Z32_FLOAT: + ext->zs_write_format = MALI_ZS_FORMAT_D32; + break; + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + /* Midgard/Bifrost support interleaved depth/stencil + * buffers, but we always treat them as multu-planar. + */ + ext->zs_write_format = MALI_ZS_FORMAT_D32; + ext->s_write_format = MALI_S_FORMAT_S8; struct panfrost_resource *stencil = rsrc->separate_stencil; struct panfrost_slice stencil_slice = stencil->slices[level]; unsigned stencil_layer_stride = (nr_samples > 1) ? stencil_slice.size0 : 0; - fbx->ds_linear.stencil = panfrost_get_texture_address(stencil, level, first_layer, 0); - fbx->ds_linear.stencil_stride = stencil_slice.stride; - fbx->ds_linear.stencil_layer_stride = stencil_layer_stride; + ext->s_writeback_base = panfrost_get_texture_address(stencil, level, first_layer, 0); + ext->s_writeback_row_stride = stencil_slice.stride; + if (rsrc->modifier != DRM_FORMAT_MOD_LINEAR) + ext->s_writeback_row_stride *= 16; + ext->s_writeback_surface_stride = stencil_layer_stride; + break; + default: + unreachable("Unsupported depth/stencil format."); } } } -/* Helper for sequential uploads used for MFBD */ - -#define UPLOAD(dest, offset, src, max) { \ - size_t sz = sizeof(*src); \ - memcpy(dest.cpu + offset, src, sz); \ - assert((offset + sz) <= max); \ - offset += sz; \ -} - -static mali_ptr -panfrost_mfbd_upload(struct panfrost_batch *batch, - struct mali_framebuffer *fb, - struct mali_framebuffer_extra *fbx, - struct mali_render_target *rts, - unsigned rt_count) +static void +panfrost_mfbd_emit_zs_crc_ext(struct panfrost_batch *batch, void *extp) { - off_t offset = 0; - - /* There may be extra data stuck in the middle */ - bool has_extra = fb->mfbd_flags & MALI_MFBD_EXTRA; - - /* Compute total size for transfer */ - - size_t total_sz = - sizeof(struct mali_framebuffer) + - (has_extra ? sizeof(struct mali_framebuffer_extra) : 0) + - sizeof(struct mali_render_target) * 8; - - struct panfrost_transfer m_f_trans = - panfrost_pool_alloc_aligned(&batch->pool, total_sz, 64); - - /* Do the transfer */ - - UPLOAD(m_f_trans, offset, fb, total_sz); - - if (has_extra) - UPLOAD(m_f_trans, offset, fbx, total_sz); - - for (unsigned c = 0; c < 8; ++c) { - UPLOAD(m_f_trans, offset, &rts[c], total_sz); + pan_pack(extp, ZS_CRC_EXTENSION, ext) { + ext.zs_clean_pixel_write_enable = true; + panfrost_mfbd_zs_crc_ext_set_bufs(batch, &ext); } - - /* Return pointer suitable for the fragment section */ - unsigned tag = - MALI_MFBD | - (has_extra ? MALI_MFBD_TAG_EXTRA : 0) | - (MALI_POSITIVE(rt_count) << 2); - - return m_f_trans.gpu | tag; } -#undef UPLOAD - /* Determines the # of bytes per pixel we need to reserve for a given format in * the tilebuffer (compared to 128-bit budget, etc). Usually the same as the * bytes per pixel of the format itself, but there are some special cases I @@ -436,102 +456,118 @@ pan_bytes_per_pixel_tib(enum pipe_format format) return desc->block.bits / 8; } -/* Determines whether a framebuffer uses too much tilebuffer space (requiring - * us to scale up the tile at a performance penalty). This is conservative but - * afaict you get 128-bits per pixel normally */ +/* Calculates the internal color buffer size and tile size based on the number + * of RT, the format and the number of pixels. If things do not fit in 4KB, we + * shrink the tile size to make it fit. + */ static unsigned -pan_tib_size(struct panfrost_batch *batch) +pan_internal_cbuf_size(struct panfrost_batch *batch, unsigned *tile_size) { - unsigned size = 0; + unsigned total_size = 0; + *tile_size = 16 * 16; for (int cb = 0; cb < batch->key.nr_cbufs; ++cb) { struct pipe_surface *surf = batch->key.cbufs[cb]; assert(surf); - size += pan_bytes_per_pixel_tib(surf->format); + + unsigned nr_samples = MAX3(surf->nr_samples, surf->texture->nr_samples, 1); + total_size += pan_bytes_per_pixel_tib(surf->format) * + nr_samples * (*tile_size); } - return size; + /* We have a 4KB budget, let's reduce the tile size until it fits. */ + while (total_size > 4096) { + total_size >>= 1; + *tile_size >>= 1; + } + + /* Align on 1k. */ + total_size = ALIGN_POT(total_size, 1024); + + /* Minimum tile size is 4x4. */ + assert(*tile_size > 4 * 4); + return total_size; } -static unsigned -pan_tib_shift(struct panfrost_batch *batch) +static void +panfrost_mfbd_emit_local_storage(struct panfrost_batch *batch, void *fb) { - unsigned size = pan_tib_size(batch); + struct panfrost_device *dev = pan_device(batch->ctx->base.screen); - if (size > 128) - return 4; - else if (size > 64) - return 5; - else if (size > 32) - return 6; - else if (size > 16) - return 7; - else - return 8; -} - -static struct mali_framebuffer -panfrost_emit_mfbd(struct panfrost_batch *batch, unsigned vertex_count) -{ - struct panfrost_context *ctx = batch->ctx; - struct pipe_context *gallium = (struct pipe_context *) ctx; - struct panfrost_device *dev = pan_device(gallium->screen); - - unsigned width = batch->key.width; - unsigned height = batch->key.height; - - struct mali_framebuffer mfbd = { - .width1 = MALI_POSITIVE(width), - .height1 = MALI_POSITIVE(height), - .width2 = MALI_POSITIVE(width), - .height2 = MALI_POSITIVE(height), - - /* Configures tib size */ - .unk1 = (pan_tib_shift(batch) << 9) | 0x80, - - .rt_count_1 = MALI_POSITIVE(MAX2(batch->key.nr_cbufs, 1)), - .rt_count_2 = 4, - }; - - if (dev->quirks & IS_BIFROST) { - mfbd.msaa.sample_locations = panfrost_emit_sample_locations(batch); - mfbd.tiler_meta = panfrost_batch_get_bifrost_tiler(batch, vertex_count); - } else { - struct mali_local_storage_packed lsp; - - pan_pack(&lsp, LOCAL_STORAGE, ls) { - if (batch->stack_size) { - unsigned shift = - panfrost_get_stack_shift(batch->stack_size); - struct panfrost_bo *bo = - panfrost_batch_get_scratchpad(batch, - batch->stack_size, - dev->thread_tls_alloc, - dev->core_count); - ls.tls_size = shift; - ls.tls_base_pointer = bo->gpu; - } - - ls.wls_instances = MALI_LOCAL_STORAGE_NO_WORKGROUP_MEM; + pan_section_pack(fb, MULTI_TARGET_FRAMEBUFFER, LOCAL_STORAGE, ls) { + if (batch->stack_size) { + unsigned shift = + panfrost_get_stack_shift(batch->stack_size); + struct panfrost_bo *bo = + panfrost_batch_get_scratchpad(batch, + batch->stack_size, + dev->thread_tls_alloc, + dev->core_count); + ls.tls_size = shift; + ls.tls_base_pointer = bo->gpu; } - mfbd.shared_memory = lsp; - struct mali_midgard_tiler_packed t; - panfrost_emit_midg_tiler(batch, &t, vertex_count); - mfbd.tiler = t; + ls.wls_instances = MALI_LOCAL_STORAGE_NO_WORKGROUP_MEM; } +} - return mfbd; +static void +panfrost_mfbd_emit_midgard_tiler(struct panfrost_batch *batch, void *fb, + unsigned vertex_count) +{ + void *t = pan_section_ptr(fb, MULTI_TARGET_FRAMEBUFFER, TILER); + + panfrost_emit_midg_tiler(batch, t, vertex_count); + + /* All weights set to 0, nothing to do here */ + pan_section_pack(fb, MULTI_TARGET_FRAMEBUFFER, TILER_WEIGHTS, w); +} + +static void +panfrost_mfbd_emit_bifrost_parameters(struct panfrost_batch *batch, void *fb) +{ + pan_section_pack(fb, MULTI_TARGET_FRAMEBUFFER, BIFROST_PARAMETERS, params) { + params.sample_locations = panfrost_emit_sample_locations(batch); + } +} + +static void +panfrost_mfbd_emit_bifrost_tiler(struct panfrost_batch *batch, void *fb, + unsigned vertex_count) +{ + pan_section_pack(fb, MULTI_TARGET_FRAMEBUFFER, BIFROST_TILER_POINTER, tiler) { + tiler.address = panfrost_batch_get_bifrost_tiler(batch, vertex_count); + } + pan_section_pack(fb, MULTI_TARGET_FRAMEBUFFER, BIFROST_PADDING, padding); } void panfrost_attach_mfbd(struct panfrost_batch *batch, unsigned vertex_count) { - struct mali_framebuffer mfbd = - panfrost_emit_mfbd(batch, vertex_count); + struct panfrost_device *dev = pan_device(batch->ctx->base.screen); + void *fb = batch->framebuffer.cpu; - memcpy(batch->framebuffer.cpu, &mfbd, sizeof(mfbd)); + if (dev->quirks & IS_BIFROST) + panfrost_mfbd_emit_bifrost_parameters(batch, fb); + else + panfrost_mfbd_emit_local_storage(batch, fb); + + pan_section_pack(fb, MULTI_TARGET_FRAMEBUFFER, PARAMETERS, params) { + params.width = batch->key.width; + params.height = batch->key.height; + params.bound_max_x = batch->key.width - 1; + params.bound_max_y = batch->key.height - 1; + params.color_buffer_allocation = + pan_internal_cbuf_size(batch, ¶ms.effective_tile_size); + params.tie_break_rule = MALI_TIE_BREAK_RULE_MINUS_180_IN_0_OUT; + params.render_target_count = MAX2(batch->key.nr_cbufs, 1); + } + + if (dev->quirks & IS_BIFROST) + panfrost_mfbd_emit_bifrost_tiler(batch, fb, vertex_count); + else + panfrost_mfbd_emit_midgard_tiler(batch, fb, vertex_count); } /* Creates an MFBD for the FRAGMENT section of the bound framebuffer */ @@ -540,64 +576,18 @@ mali_ptr panfrost_mfbd_fragment(struct panfrost_batch *batch, bool has_draws) { struct panfrost_device *dev = pan_device(batch->ctx->base.screen); - bool is_bifrost = dev->quirks & IS_BIFROST; + unsigned vertex_count = has_draws; + struct panfrost_transfer t = + panfrost_pool_alloc_aligned(&batch->pool, + panfrost_mfbd_size(batch), 64); + void *fb = t.cpu, *zs_crc_ext, *rts; - struct mali_framebuffer fb = panfrost_emit_mfbd(batch, has_draws); - struct mali_framebuffer_extra fbx = {0}; - struct mali_render_target rts[8] = {0}; - - /* We always upload at least one dummy GL_NONE render target */ - - unsigned rt_descriptors = MAX2(batch->key.nr_cbufs, 1); - - fb.rt_count_1 = MALI_POSITIVE(rt_descriptors); - fb.mfbd_flags = 0x100; - - panfrost_mfbd_clear(batch, &fb, &fbx, rts, rt_descriptors); - - /* Upload either the render target or a dummy GL_NONE target */ - - unsigned offset = 0; - unsigned tib_shift = pan_tib_shift(batch); - - for (int cb = 0; cb < rt_descriptors; ++cb) { - struct pipe_surface *surf = batch->key.cbufs[cb]; - unsigned rt_offset = offset << tib_shift; - - if (surf && ((batch->clear | batch->draws) & (PIPE_CLEAR_COLOR0 << cb))) { - if (MAX2(surf->nr_samples, surf->texture->nr_samples) > 1) - batch->requirements |= PAN_REQ_MSAA; - - panfrost_mfbd_set_cbuf(&rts[cb], surf); - - offset += pan_bytes_per_pixel_tib(surf->format); - } else { - struct mali_rt_format null_rt = { - .unk1 = 0x4000000, - .no_preload = true - }; - - if (is_bifrost) { - null_rt.flags = 0x2; - null_rt.unk3 = 0x8; - } - - rts[cb].format = null_rt; - rts[cb].framebuffer = 0; - rts[cb].framebuffer_stride = 0; - } - - /* TODO: Break out the field */ - rts[cb].format.unk1 |= rt_offset; - } - - fb.rt_count_2 = MAX2(DIV_ROUND_UP(offset, 1 << (10 - tib_shift)), 1); - - if (batch->key.zsbuf && ((batch->clear | batch->draws) & PIPE_CLEAR_DEPTHSTENCIL)) { - if (MAX2(batch->key.zsbuf->nr_samples, batch->key.zsbuf->nr_samples) > 1) - batch->requirements |= PAN_REQ_MSAA; - - panfrost_mfbd_set_zsbuf(&fb, &fbx, batch->key.zsbuf); + if (panfrost_mfbd_has_zs_crc_ext(batch)) { + zs_crc_ext = fb + MALI_MULTI_TARGET_FRAMEBUFFER_LENGTH; + rts = zs_crc_ext + MALI_ZS_CRC_EXTENSION_LENGTH; + } else { + zs_crc_ext = NULL; + rts = fb + MALI_MULTI_TARGET_FRAMEBUFFER_LENGTH; } /* When scanning out, the depth buffer is immediately invalidated, so @@ -611,36 +601,88 @@ panfrost_mfbd_fragment(struct panfrost_batch *batch, bool has_draws) if (panfrost_batch_is_scanout(batch)) batch->requirements &= ~PAN_REQ_DEPTH_WRITE; - /* Actualize the requirements */ + if (zs_crc_ext) { + if (batch->key.zsbuf && + MAX2(batch->key.zsbuf->nr_samples, batch->key.zsbuf->nr_samples) > 1) + batch->requirements |= PAN_REQ_MSAA; - if (batch->requirements & PAN_REQ_MSAA) { - /* XXX */ - fb.unk1 |= (1 << 4) | (1 << 1); - fb.rt_count_2 = 4; + panfrost_mfbd_emit_zs_crc_ext(batch, zs_crc_ext); } - if (batch->requirements & PAN_REQ_DEPTH_WRITE) - fb.mfbd_flags |= MALI_MFBD_DEPTH_WRITE; + /* We always upload at least one dummy GL_NONE render target */ - /* Checksumming only works with a single render target */ + unsigned rt_descriptors = MAX2(batch->key.nr_cbufs, 1); - if (batch->key.nr_cbufs == 1) { - struct pipe_surface *surf = batch->key.cbufs[0]; - struct panfrost_resource *rsrc = pan_resource(surf->texture); + /* Upload either the render target or a dummy GL_NONE target */ - if (rsrc->checksummed) { - unsigned level = surf->u.tex.level; - struct panfrost_slice *slice = &rsrc->slices[level]; + unsigned rt_offset = 0, tib_size; + unsigned internal_cbuf_size = pan_internal_cbuf_size(batch, &tib_size); - fb.mfbd_flags |= MALI_MFBD_EXTRA; - fbx.flags_hi |= MALI_EXTRA_PRESENT; - fbx.checksum_stride = slice->checksum_stride; - if (slice->checksum_bo) - fbx.checksum = slice->checksum_bo->gpu; - else - fbx.checksum = rsrc->bo->gpu + slice->checksum_offset; + for (int cb = 0; cb < rt_descriptors; ++cb) { + struct pipe_surface *surf = batch->key.cbufs[cb]; + void *rt = rts + (cb * MALI_RENDER_TARGET_LENGTH); + + if (!((batch->clear | batch->draws) & (PIPE_CLEAR_COLOR0 << cb))) + surf = NULL; + + panfrost_mfbd_emit_rt(batch, rt, surf, rt_offset, cb); + + if (surf) { + if (MAX2(surf->nr_samples, surf->texture->nr_samples) > 1) + batch->requirements |= PAN_REQ_MSAA; + + rt_offset += pan_bytes_per_pixel_tib(surf->format) * tib_size; } } - return panfrost_mfbd_upload(batch, &fb, &fbx, rts, rt_descriptors); + if (dev->quirks & IS_BIFROST) + panfrost_mfbd_emit_bifrost_parameters(batch, fb); + else + panfrost_mfbd_emit_local_storage(batch, fb); + + pan_section_pack(fb, MULTI_TARGET_FRAMEBUFFER, PARAMETERS, params) { + params.width = batch->key.width; + params.height = batch->key.height; + params.bound_max_x = batch->key.width - 1; + params.bound_max_y = batch->key.height - 1; + params.effective_tile_size = tib_size; + params.tie_break_rule = MALI_TIE_BREAK_RULE_MINUS_180_IN_0_OUT; + params.render_target_count = rt_descriptors; + params.z_internal_format = get_z_internal_format(batch); + + if (batch->clear & PIPE_CLEAR_DEPTH) + params.z_clear = batch->clear_depth; + if (batch->clear & PIPE_CLEAR_STENCIL) + params.s_clear = batch->clear_stencil & 0xff; + + params.color_buffer_allocation = internal_cbuf_size; + + if (batch->requirements & PAN_REQ_MSAA) { + /* MSAA 4x */ + params.sample_count = 4; + params.sample_pattern = MALI_SAMPLE_PATTERN_ROTATED_4X_GRID; + } + + if (batch->key.zsbuf && + ((batch->clear | batch->draws) & PIPE_CLEAR_DEPTHSTENCIL)) { + params.z_write_enable = true; + if (batch->key.zsbuf->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT) + params.s_write_enable = true; + } + + params.has_zs_crc_extension = !!zs_crc_ext; + } + + if (dev->quirks & IS_BIFROST) + panfrost_mfbd_emit_bifrost_tiler(batch, fb, vertex_count); + else + panfrost_mfbd_emit_midgard_tiler(batch, fb, vertex_count); + + /* Return pointer suitable for the fragment section */ + unsigned tag = + MALI_FBD_TAG_IS_MFBD | + (zs_crc_ext ? MALI_FBD_TAG_HAS_ZS_RT : 0) | + (MALI_POSITIVE(rt_descriptors) << 2); + + return t.gpu | tag; } diff --git a/src/panfrost/include/panfrost-job.h b/src/panfrost/include/panfrost-job.h index c0390cdb43b..4ecf9c3c9cc 100644 --- a/src/panfrost/include/panfrost-job.h +++ b/src/panfrost/include/panfrost-job.h @@ -392,14 +392,6 @@ struct mali_payload_write_value { * 4. Otherwise, set magic_divisor = m and extra_flags = 0. */ -#define FBD_MASK (~0x3f) - -/* MFBD, rather than SFBD */ -#define MALI_MFBD (0x1) - -/* ORed into an MFBD address to specify the fbx section is included */ -#define MALI_MFBD_TAG_EXTRA (0x2) - /* On Bifrost, these fields are the same between the vertex and tiler payloads. * They also seem to be the same between Bifrost and Midgard. They're shared in * fused payloads. @@ -518,187 +510,4 @@ struct mali_payload_fragment { mali_ptr framebuffer; } __attribute__((packed)); -/* Configures multisampling on Bifrost fragment jobs */ - -struct bifrost_multisampling { - u64 zero1; - u64 zero2; - mali_ptr sample_locations; - u64 zero4; -} __attribute__((packed)); - -#define MALI_MFBD_FORMAT_SRGB (1 << 0) - -struct mali_rt_format { - unsigned unk1 : 32; - unsigned unk2 : 3; - - unsigned nr_channels : 2; /* MALI_POSITIVE */ - - unsigned unk3 : 4; - unsigned unk4 : 1; - enum mali_block_format block : 2; - enum mali_msaa msaa : 2; - unsigned flags : 2; - - unsigned swizzle : 12; - - unsigned zero : 3; - - /* Disables MFBD preload. When this bit is set, the render target will - * be cleared every frame. When this bit is clear, the hardware will - * automatically wallpaper the render target back from main memory. - * Unfortunately, MFBD preload is very broken on Midgard, so in - * practice, this is a chicken bit that should always be set. - * Discovered by accident, as all good chicken bits are. */ - - unsigned no_preload : 1; -} __attribute__((packed)); - -/* Flags for afbc.flags and ds_afbc.flags */ - -#define MALI_AFBC_FLAGS 0x10009 - -/* Lossless RGB and RGBA colorspace transform */ -#define MALI_AFBC_YTR (1 << 17) - -struct mali_render_target { - struct mali_rt_format format; - - u64 zero1; - - struct { - /* Stuff related to ARM Framebuffer Compression. When AFBC is enabled, - * there is an extra metadata buffer that contains 16 bytes per tile. - * The framebuffer needs to be the same size as before, since we don't - * know ahead of time how much space it will take up. The - * framebuffer_stride is set to 0, since the data isn't stored linearly - * anymore. - * - * When AFBC is disabled, these fields are zero. - */ - - mali_ptr metadata; - u32 stride; // stride in units of tiles - u32 flags; // = 0x20000 - } afbc; - - mali_ptr framebuffer; - - u32 zero2 : 4; - u32 framebuffer_stride : 28; // in units of bytes, row to next - u32 layer_stride; /* For multisample rendering */ - - 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? -} __attribute__((packed)); - -/* An optional part of mali_framebuffer. It comes between the main structure - * and the array of render targets. It must be included if any of these are - * enabled: - * - * - Transaction Elimination - * - Depth/stencil - * - TODO: Anything else? - */ - -/* flags_hi */ -#define MALI_EXTRA_PRESENT (0x1) - -/* flags_lo */ -#define MALI_EXTRA_ZS (0x4) - -struct mali_framebuffer_extra { - mali_ptr checksum; - /* Each tile has an 8 byte checksum, so the stride is "width in tiles * 8" */ - u32 checksum_stride; - - unsigned flags_lo : 4; - enum mali_block_format zs_block : 2; - - /* Number of samples in Z/S attachment, MALI_POSITIVE. So zero for - * 1-sample (non-MSAA), 0x3 for MSAA 4x, etc */ - unsigned zs_samples : 4; - unsigned flags_hi : 22; - - union { - /* Note: AFBC is only allowed for 24/8 combined depth/stencil. */ - struct { - mali_ptr depth_stencil_afbc_metadata; - u32 depth_stencil_afbc_stride; // in units of tiles - u32 flags; - - mali_ptr depth_stencil; - - u64 padding; - } ds_afbc; - - struct { - /* Depth becomes depth/stencil in case of combined D/S */ - mali_ptr depth; - u32 depth_stride_zero : 4; - u32 depth_stride : 28; - u32 depth_layer_stride; - - mali_ptr stencil; - u32 stencil_stride_zero : 4; - u32 stencil_stride : 28; - u32 stencil_layer_stride; - } ds_linear; - }; - - - u32 clear_color_1; - u32 clear_color_2; - u64 zero3; -} __attribute__((packed)); - -/* Flags for mfbd_flags */ - -/* Enables writing depth results back to main memory (rather than keeping them - * on-chip in the tile buffer and then discarding) */ - -#define MALI_MFBD_DEPTH_WRITE (1 << 10) - -/* The MFBD contains the extra mali_framebuffer_extra section */ - -#define MALI_MFBD_EXTRA (1 << 13) - -struct mali_framebuffer { - union { - struct mali_local_storage_packed shared_memory; - struct bifrost_multisampling msaa; - }; - - /* 0x20 */ - u16 width1, height1; - u32 zero3; - u16 width2, height2; - u32 unk1 : 19; // = 0x01000 - u32 rt_count_1 : 3; // off-by-one (use MALI_POSITIVE) - u32 unk2 : 2; // = 0 - u32 rt_count_2 : 3; // no off-by-one - u32 zero4 : 5; - /* 0x30 */ - u32 clear_stencil : 8; - u32 mfbd_flags : 24; // = 0x100 - float clear_depth; - - union { - struct { - struct mali_midgard_tiler_packed tiler; - struct mali_midgard_tiler_weights_packed tiler_weights; - }; - struct { - mali_ptr tiler_meta; - u32 zeros[16]; - }; - }; - - /* optional: struct mali_framebuffer_extra extra */ - /* struct mali_render_target rts[] */ -} __attribute__((packed)); - #endif /* __PANFROST_JOB_H__ */ diff --git a/src/panfrost/lib/decode.c b/src/panfrost/lib/decode.c index 544b0d1ebd4..58765f19df0 100644 --- a/src/panfrost/lib/decode.c +++ b/src/panfrost/lib/decode.c @@ -183,76 +183,6 @@ pandecode_validate_buffer(mali_ptr addr, size_t sz) } } -struct pandecode_flag_info { - u64 flag; - const char *name; -}; - -static void -pandecode_log_decoded_flags(const struct pandecode_flag_info *flag_info, - u64 flags) -{ - bool decodable_flags_found = false; - - for (int i = 0; flag_info[i].name; i++) { - if ((flags & flag_info[i].flag) != flag_info[i].flag) - continue; - - if (!decodable_flags_found) { - decodable_flags_found = true; - } else { - pandecode_log_cont(" | "); - } - - pandecode_log_cont("%s", flag_info[i].name); - - flags &= ~flag_info[i].flag; - } - - if (decodable_flags_found) { - if (flags) - pandecode_log_cont(" | 0x%" PRIx64, flags); - } else { - pandecode_log_cont("0x%" PRIx64, flags); - } -} - -#define FLAG_INFO(flag) { MALI_MFBD_FORMAT_##flag, "MALI_MFBD_FORMAT_" #flag } -static const struct pandecode_flag_info mfbd_fmt_flag_info[] = { - FLAG_INFO(SRGB), - {} -}; -#undef FLAG_INFO - -#define FLAG_INFO(flag) { MALI_AFBC_##flag, "MALI_AFBC_" #flag } -static const struct pandecode_flag_info afbc_fmt_flag_info[] = { - FLAG_INFO(YTR), - {} -}; -#undef FLAG_INFO - -#define FLAG_INFO(flag) { MALI_EXTRA_##flag, "MALI_EXTRA_" #flag } -static const struct pandecode_flag_info mfbd_extra_flag_hi_info[] = { - FLAG_INFO(PRESENT), - {} -}; -#undef FLAG_INFO - -#define FLAG_INFO(flag) { MALI_EXTRA_##flag, "MALI_EXTRA_" #flag } -static const struct pandecode_flag_info mfbd_extra_flag_lo_info[] = { - FLAG_INFO(ZS), - {} -}; -#undef FLAG_INFO - -#define FLAG_INFO(flag) { MALI_MFBD_##flag, "MALI_MFBD_" #flag } -static const struct pandecode_flag_info mfbd_flag_info [] = { - FLAG_INFO(DEPTH_WRITE), - FLAG_INFO(EXTRA), - {} -}; -#undef FLAG_INFO - /* Midgard's tiler descriptor is embedded within the * larger FBD */ @@ -350,30 +280,6 @@ pandecode_midgard_tiler_descriptor( DUMP_UNPACKED(MIDGARD_TILER_WEIGHTS, w, "Tiler Weights:\n"); } -/* TODO: The Bifrost tiler is not understood at all yet */ - -static void -pandecode_bifrost_tiler_descriptor(const struct mali_framebuffer *fb) -{ - pandecode_log(".tiler = {\n"); - pandecode_indent++; - - MEMORY_PROP(fb, tiler_meta); - - for (int i = 0; i < 16; i++) { - if (fb->zeros[i] != 0) { - pandecode_msg("XXX: tiler descriptor zero %d tripped, value %x\n", - i, fb->zeros[i]); - } - } - - pandecode_log("},\n"); - - pandecode_indent--; - pandecode_log("}\n"); - -} - /* Information about the framebuffer passed back for * additional analysis */ @@ -524,111 +430,49 @@ pandecode_swizzle(unsigned swizzle, enum mali_format format) } static void -pandecode_rt_format(struct mali_rt_format format) +pandecode_render_target(uint64_t gpu_va, unsigned job_no, bool is_bifrost, unsigned gpu_id, + const struct MALI_MULTI_TARGET_FRAMEBUFFER_PARAMETERS *fb) { - pandecode_log(".format = {\n"); + pandecode_log("Color Render Targets:\n"); pandecode_indent++; - pandecode_prop("unk1 = 0x%" PRIx32, format.unk1); - pandecode_prop("unk2 = 0x%" PRIx32, format.unk2); - pandecode_prop("unk3 = 0x%" PRIx32, format.unk3); - pandecode_prop("unk4 = 0x%" PRIx32, format.unk4); - - pandecode_prop("block = %s", mali_block_format_as_str(format.block)); - - /* 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(".flags = "); - pandecode_log_decoded_flags(mfbd_fmt_flag_info, format.flags); - pandecode_log_cont(",\n"); - - pandecode_prop("msaa = %s", mali_msaa_as_str(format.msaa)); - - /* In theory, the no_preload bit can be cleared to enable MFBD preload, - * which is a faster hardware-based alternative to the wallpaper method - * to preserve framebuffer contents across frames. In practice, MFBD - * preload is buggy on Midgard, and so this is a chicken bit. If this - * bit isn't set, most likely something broke unrelated to preload */ - - if (!format.no_preload) { - pandecode_msg("XXX: buggy MFBD preload enabled - chicken bit should be clear\n"); - pandecode_prop("no_preload = 0x%" PRIx32, format.no_preload); + for (int i = 0; i < (fb->render_target_count); i++) { + mali_ptr rt_va = gpu_va + i * MALI_RENDER_TARGET_LENGTH; + struct pandecode_mapped_memory *mem = + pandecode_find_mapped_gpu_mem_containing(rt_va); + const struct mali_render_target_packed *PANDECODE_PTR_VAR(rtp, mem, (mali_ptr) rt_va); + DUMP_CL(RENDER_TARGET, rtp, "Color Render Target %d:\n", i); } - if (format.zero) - pandecode_prop("zero = 0x%" PRIx32, format.zero); - pandecode_indent--; - pandecode_log("},\n"); + pandecode_log("\n"); } static void -pandecode_render_target(uint64_t gpu_va, unsigned job_no, const struct mali_framebuffer *fb) +pandecode_mfbd_bifrost_deps(const void *fb, int job_no) { - pandecode_log("struct mali_render_target rts_list_%"PRIx64"_%d[] = {\n", gpu_va, job_no); + pan_section_unpack(fb, MULTI_TARGET_FRAMEBUFFER, BIFROST_PARAMETERS, params); + + /* The blob stores all possible sample locations in a single buffer + * allocated on startup, and just switches the pointer when switching + * MSAA state. For now, we just put the data into the cmdstream, but we + * should do something like what the blob does with a real driver. + * + * There seem to be 32 slots for sample locations, followed by another + * 16. The second 16 is just the center location followed by 15 zeros + * in all the cases I've identified (maybe shader vs. depth/color + * samples?). + */ + + struct pandecode_mapped_memory *smem = + pandecode_find_mapped_gpu_mem_containing(params.sample_locations); + + const u16 *PANDECODE_PTR_VAR(samples, smem, params.sample_locations); + + pandecode_log("uint16_t sample_locations_%d[] = {\n", job_no); pandecode_indent++; - - for (int i = 0; i < (fb->rt_count_1 + 1); i++) { - mali_ptr rt_va = gpu_va + i * sizeof(struct mali_render_target); - struct pandecode_mapped_memory *mem = - pandecode_find_mapped_gpu_mem_containing(rt_va); - const struct mali_render_target *PANDECODE_PTR_VAR(rt, mem, (mali_ptr) rt_va); - - pandecode_log("{\n"); - pandecode_indent++; - - pandecode_rt_format(rt->format); - - if (rt->format.block == MALI_BLOCK_FORMAT_AFBC) { - pandecode_log(".afbc = {\n"); - pandecode_indent++; - - char *a = pointer_as_memory_reference(rt->afbc.metadata); - pandecode_prop("metadata = %s", a); - free(a); - - pandecode_prop("stride = %d", rt->afbc.stride); - - pandecode_log(".flags = "); - pandecode_log_decoded_flags(afbc_fmt_flag_info, rt->afbc.flags); - pandecode_log_cont(",\n"); - - pandecode_indent--; - pandecode_log("},\n"); - } else if (rt->afbc.metadata || rt->afbc.stride || rt->afbc.flags) { - pandecode_msg("XXX: AFBC disabled but AFBC field set (0x%lX, 0x%x, 0x%x)\n", - rt->afbc.metadata, - rt->afbc.stride, - rt->afbc.flags); - } - - MEMORY_PROP(rt, framebuffer); - pandecode_prop("framebuffer_stride = %d", rt->framebuffer_stride); - - if (rt->layer_stride) - pandecode_prop("layer_stride = %d", rt->layer_stride); - - if (rt->clear_color_1 | rt->clear_color_2 | rt->clear_color_3 | rt->clear_color_4) { - pandecode_prop("clear_color_1 = 0x%" PRIx32, rt->clear_color_1); - pandecode_prop("clear_color_2 = 0x%" PRIx32, rt->clear_color_2); - pandecode_prop("clear_color_3 = 0x%" PRIx32, rt->clear_color_3); - pandecode_prop("clear_color_4 = 0x%" PRIx32, rt->clear_color_4); - } - - if (rt->zero1 || rt->zero2) { - pandecode_msg("XXX: render target zeros tripped\n"); - pandecode_prop("zero1 = 0x%" PRIx64, rt->zero1); - pandecode_prop("zero2 = 0x%" PRIx32, rt->zero2); - } - - pandecode_indent--; - pandecode_log("},\n"); + for (int i = 0; i < 32 + 16; i++) { + pandecode_log("%d, %d,\n", samples[2 * i], samples[2 * i + 1]); } pandecode_indent--; @@ -636,212 +480,66 @@ pandecode_render_target(uint64_t gpu_va, unsigned job_no, const struct mali_fram } static struct pandecode_fbd -pandecode_mfbd_bfr(uint64_t gpu_va, int job_no, bool is_fragment, bool is_compute, bool is_bifrost) +pandecode_mfbd_bfr(uint64_t gpu_va, int job_no, bool is_fragment, bool is_compute, bool is_bifrost, unsigned gpu_id) { struct pandecode_mapped_memory *mem = pandecode_find_mapped_gpu_mem_containing(gpu_va); - const struct mali_framebuffer *PANDECODE_PTR_VAR(fb, mem, (mali_ptr) gpu_va); + const void *PANDECODE_PTR_VAR(fb, mem, (mali_ptr) gpu_va); + pan_section_unpack(fb, MULTI_TARGET_FRAMEBUFFER, PARAMETERS, params); struct pandecode_fbd info; - if (is_bifrost && fb->msaa.sample_locations) { - /* The blob stores all possible sample locations in a single buffer - * allocated on startup, and just switches the pointer when switching - * MSAA state. For now, we just put the data into the cmdstream, but we - * should do something like what the blob does with a real driver. - * - * There seem to be 32 slots for sample locations, followed by another - * 16. The second 16 is just the center location followed by 15 zeros - * in all the cases I've identified (maybe shader vs. depth/color - * samples?). - */ - - struct pandecode_mapped_memory *smem = pandecode_find_mapped_gpu_mem_containing(fb->msaa.sample_locations); - - const u16 *PANDECODE_PTR_VAR(samples, smem, fb->msaa.sample_locations); - - pandecode_log("uint16_t sample_locations_%d[] = {\n", job_no); - pandecode_indent++; - - for (int i = 0; i < 32 + 16; i++) { - pandecode_log("%d, %d,\n", samples[2 * i], samples[2 * i + 1]); - } - - pandecode_indent--; - pandecode_log("};\n"); - } + if (is_bifrost) + pandecode_mfbd_bifrost_deps(fb, job_no); - pandecode_log("struct mali_framebuffer framebuffer_%"PRIx64"_%d = {\n", gpu_va, job_no); + pandecode_log("Multi-Target Framebuffer:\n"); pandecode_indent++; if (is_bifrost) { - pandecode_log(".msaa = {\n"); - pandecode_indent++; - - if (fb->msaa.sample_locations) - pandecode_prop("sample_locations = sample_locations_%d", job_no); - else - pandecode_msg("XXX: sample_locations missing\n"); - - if (fb->msaa.zero1 || fb->msaa.zero2 || fb->msaa.zero4) { - pandecode_msg("XXX: multisampling zero tripped\n"); - pandecode_prop("zero1 = %" PRIx64, fb->msaa.zero1); - pandecode_prop("zero2 = %" PRIx64, fb->msaa.zero2); - pandecode_prop("zero4 = %" PRIx64, fb->msaa.zero4); - } - - pandecode_indent--; - pandecode_log("},\n"); + DUMP_SECTION(MULTI_TARGET_FRAMEBUFFER, BIFROST_PARAMETERS, fb, "Bifrost Params:\n"); } else { - struct mali_local_storage_packed ls = fb->shared_memory; - DUMP_CL(LOCAL_STORAGE, &ls, "Local Storage:\n"); + DUMP_SECTION(MULTI_TARGET_FRAMEBUFFER, LOCAL_STORAGE, fb, "Local Storage:\n"); } - info.width = fb->width1 + 1; - info.height = fb->height1 + 1; - info.rt_count = fb->rt_count_1 + 1; + info.width = params.width; + info.height = params.height; + info.rt_count = params.render_target_count; + DUMP_UNPACKED(MULTI_TARGET_FRAMEBUFFER_PARAMETERS, params, "Parameters:\n"); - pandecode_prop("width1 = MALI_POSITIVE(%d)", fb->width1 + 1); - pandecode_prop("height1 = MALI_POSITIVE(%d)", fb->height1 + 1); - pandecode_prop("width2 = MALI_POSITIVE(%d)", fb->width2 + 1); - pandecode_prop("height2 = MALI_POSITIVE(%d)", fb->height2 + 1); - - pandecode_prop("unk1 = 0x%x", fb->unk1); - pandecode_prop("unk2 = 0x%x", fb->unk2); - pandecode_prop("rt_count_1 = MALI_POSITIVE(%d)", fb->rt_count_1 + 1); - pandecode_prop("rt_count_2 = %d", fb->rt_count_2); - - pandecode_log(".mfbd_flags = "); - pandecode_log_decoded_flags(mfbd_flag_info, fb->mfbd_flags); - pandecode_log_cont(",\n"); - - if (fb->clear_stencil) - pandecode_prop("clear_stencil = 0x%x", fb->clear_stencil); - - if (fb->clear_depth) - pandecode_prop("clear_depth = %f", fb->clear_depth); - - if (!is_compute) - if (is_bifrost) - pandecode_bifrost_tiler_descriptor(fb); - else { - 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); + if (!is_compute) { + if (is_bifrost) { + DUMP_SECTION(MULTI_TARGET_FRAMEBUFFER, BIFROST_TILER_POINTER, fb, "Tiler Pointer"); + } else { + const void *t = pan_section_ptr(fb, MULTI_TARGET_FRAMEBUFFER, TILER); + const void *w = pan_section_ptr(fb, MULTI_TARGET_FRAMEBUFFER, TILER_WEIGHTS); + pandecode_midgard_tiler_descriptor(t, w, params.width, params.height, is_fragment, true); } - else + } else { pandecode_msg("XXX: skipping compute MFBD, fixme\n"); + } - if (fb->zero3 || fb->zero4) { - pandecode_msg("XXX: framebuffer zeros tripped\n"); - pandecode_prop("zero3 = 0x%" PRIx32, fb->zero3); - pandecode_prop("zero4 = 0x%" PRIx32, fb->zero4); + if (is_bifrost) { + pan_section_unpack(fb, MULTI_TARGET_FRAMEBUFFER, BIFROST_PADDING, padding); } pandecode_indent--; - pandecode_log("};\n"); + pandecode_log("\n"); - gpu_va += sizeof(struct mali_framebuffer); + gpu_va += MALI_MULTI_TARGET_FRAMEBUFFER_LENGTH; - info.has_extra = (fb->mfbd_flags & MALI_MFBD_EXTRA) && is_fragment; + info.has_extra = params.has_zs_crc_extension; if (info.has_extra) { - mem = pandecode_find_mapped_gpu_mem_containing(gpu_va); - const struct mali_framebuffer_extra *PANDECODE_PTR_VAR(fbx, mem, (mali_ptr) gpu_va); + struct pandecode_mapped_memory *mem = + pandecode_find_mapped_gpu_mem_containing(gpu_va); + const struct mali_zs_crc_extension_packed *PANDECODE_PTR_VAR(zs_crc, mem, (mali_ptr)gpu_va); + DUMP_CL(ZS_CRC_EXTENSION, zs_crc, "ZS CRC Extension:\n"); + pandecode_log("\n"); - pandecode_log("struct mali_framebuffer_extra fb_extra_%"PRIx64"_%d = {\n", gpu_va, job_no); - pandecode_indent++; - - MEMORY_PROP(fbx, checksum); - - if (fbx->checksum_stride) - pandecode_prop("checksum_stride = %d", fbx->checksum_stride); - - pandecode_log(".flags_hi = "); - pandecode_log_decoded_flags(mfbd_extra_flag_hi_info, fbx->flags_hi); - pandecode_log_cont(",\n"); - - pandecode_log(".flags_lo = "); - pandecode_log_decoded_flags(mfbd_extra_flag_lo_info, fbx->flags_lo); - pandecode_log_cont(",\n"); - - pandecode_prop("zs_block = %s", mali_block_format_as_str(fbx->zs_block)); - pandecode_prop("zs_samples = MALI_POSITIVE(%u)", fbx->zs_samples + 1); - - if (fbx->zs_block == MALI_BLOCK_FORMAT_AFBC) { - pandecode_log(".ds_afbc = {\n"); - pandecode_indent++; - - MEMORY_PROP_DIR(fbx->ds_afbc, depth_stencil_afbc_metadata); - pandecode_prop("depth_stencil_afbc_stride = %d", - fbx->ds_afbc.depth_stencil_afbc_stride); - MEMORY_PROP_DIR(fbx->ds_afbc, depth_stencil); - - pandecode_log(".flags = "); - pandecode_log_decoded_flags(afbc_fmt_flag_info, fbx->ds_afbc.flags); - pandecode_log_cont(",\n"); - - if (fbx->ds_afbc.padding) { - pandecode_msg("XXX: Depth/stencil AFBC zeros tripped\n"); - pandecode_prop("padding = 0x%" PRIx64, fbx->ds_afbc.padding); - } - - pandecode_indent--; - pandecode_log("},\n"); - } else { - pandecode_log(".ds_linear = {\n"); - pandecode_indent++; - - if (fbx->ds_linear.depth) { - MEMORY_PROP_DIR(fbx->ds_linear, depth); - pandecode_prop("depth_stride = %d", - fbx->ds_linear.depth_stride); - pandecode_prop("depth_layer_stride = %d", - fbx->ds_linear.depth_layer_stride); - } else if (fbx->ds_linear.depth_stride || fbx->ds_linear.depth_layer_stride) { - pandecode_msg("XXX: depth stride zero tripped %d %d\n", fbx->ds_linear.depth_stride, fbx->ds_linear.depth_layer_stride); - } - - if (fbx->ds_linear.stencil) { - MEMORY_PROP_DIR(fbx->ds_linear, stencil); - pandecode_prop("stencil_stride = %d", - fbx->ds_linear.stencil_stride); - pandecode_prop("stencil_layer_stride = %d", - fbx->ds_linear.stencil_layer_stride); - } else if (fbx->ds_linear.stencil_stride || fbx->ds_linear.stencil_layer_stride) { - pandecode_msg("XXX: stencil stride zero tripped %d %d\n", fbx->ds_linear.stencil_stride, fbx->ds_linear.stencil_layer_stride); - } - - if (fbx->ds_linear.depth_stride_zero || - fbx->ds_linear.stencil_stride_zero) { - pandecode_msg("XXX: Depth/stencil zeros tripped\n"); - pandecode_prop("depth_stride_zero = 0x%x", - fbx->ds_linear.depth_stride_zero); - pandecode_prop("stencil_stride_zero = 0x%x", - fbx->ds_linear.stencil_stride_zero); - } - - pandecode_indent--; - pandecode_log("},\n"); - } - - if (fbx->clear_color_1 | fbx->clear_color_2) { - pandecode_prop("clear_color_1 = 0x%" PRIx32, fbx->clear_color_1); - pandecode_prop("clear_color_2 = 0x%" PRIx32, fbx->clear_color_2); - } - - if (fbx->zero3) { - pandecode_msg("XXX: fb_extra zeros tripped\n"); - pandecode_prop("zero3 = 0x%" PRIx64, fbx->zero3); - } - - pandecode_indent--; - pandecode_log("};\n"); - - gpu_va += sizeof(struct mali_framebuffer_extra); + gpu_va += MALI_ZS_CRC_EXTENSION_LENGTH; } if (is_fragment) - pandecode_render_target(gpu_va, job_no, fb); + pandecode_render_target(gpu_va, job_no, is_bifrost, gpu_id, ¶ms); return info; } @@ -1412,8 +1110,9 @@ pandecode_vertex_tiler_postfix_pre( if (is_bifrost) pandecode_compute_fbd(p->shared & ~1, job_no); - else if (p->shared & MALI_MFBD) - fbd_info = pandecode_mfbd_bfr((u64) ((uintptr_t) p->shared) & FBD_MASK, job_no, false, job_type == MALI_JOB_TYPE_COMPUTE, false); + else if (p->shared & MALI_FBD_TAG_IS_MFBD) + fbd_info = pandecode_mfbd_bfr((u64) ((uintptr_t) p->shared) & ~MALI_FBD_TAG_MASK, + job_no, false, job_type == MALI_JOB_TYPE_COMPUTE, is_bifrost, gpu_id); else if (job_type == MALI_JOB_TYPE_COMPUTE) pandecode_compute_fbd((u64) (uintptr_t) p->shared, job_no); else @@ -1509,7 +1208,8 @@ pandecode_vertex_tiler_postfix_pre( /* MRT blend fields are used whenever MFBD is used, with * per-RT descriptors */ - if (job_type == MALI_JOB_TYPE_TILER && (is_bifrost || p->shared & MALI_MFBD)) { + if (job_type == MALI_JOB_TYPE_TILER && + (is_bifrost || p->shared & MALI_FBD_TAG_IS_MFBD)) { void* blend_base = ((void *) cl) + MALI_STATE_LENGTH; for (unsigned i = 0; i < fbd_info.rt_count; i++) { @@ -1706,7 +1406,7 @@ pandecode_fragment_job(const struct pandecode_mapped_memory *mem, { const struct mali_payload_fragment *PANDECODE_PTR_VAR(s, mem, payload); - bool is_mfbd = s->framebuffer & MALI_MFBD; + bool is_mfbd = s->framebuffer & MALI_FBD_TAG_IS_MFBD; if (!is_mfbd && is_bifrost) pandecode_msg("XXX: Bifrost fragment must use MFBD\n"); @@ -1714,20 +1414,22 @@ pandecode_fragment_job(const struct pandecode_mapped_memory *mem, struct pandecode_fbd info; if (is_mfbd) - info = pandecode_mfbd_bfr(s->framebuffer & FBD_MASK, job_no, true, false, is_bifrost); + info = pandecode_mfbd_bfr(s->framebuffer & ~MALI_FBD_TAG_MASK, job_no, + true, false, is_bifrost, gpu_id); else - info = pandecode_sfbd(s->framebuffer & FBD_MASK, job_no, true, gpu_id); + info = pandecode_sfbd(s->framebuffer & ~MALI_FBD_TAG_MASK, job_no, + true, gpu_id); /* Compute the tag for the tagged pointer. This contains the type of * FBD (MFBD/SFBD), and in the case of an MFBD, information about which * additional structures follow the MFBD header (an extra payload or * not, as well as a count of render targets) */ - unsigned expected_tag = is_mfbd ? MALI_MFBD : 0; + unsigned expected_tag = is_mfbd ? MALI_FBD_TAG_IS_MFBD : 0; if (is_mfbd) { if (info.has_extra) - expected_tag |= MALI_MFBD_TAG_EXTRA; + expected_tag |= MALI_FBD_TAG_HAS_ZS_RT; expected_tag |= (MALI_POSITIVE(info.rt_count) << 2); } @@ -1780,7 +1482,7 @@ pandecode_fragment_job(const struct pandecode_mapped_memory *mem, /* The FBD is a tagged pointer */ - unsigned tag = (s->framebuffer & ~FBD_MASK); + unsigned tag = (s->framebuffer & MALI_FBD_TAG_MASK); if (tag != expected_tag) pandecode_msg("XXX: expected FBD tag %X but got %X\n", expected_tag, tag); diff --git a/src/panfrost/lib/midgard.xml b/src/panfrost/lib/midgard.xml index 4466e11082b..53aadda80e8 100644 --- a/src/panfrost/lib/midgard.xml +++ b/src/panfrost/lib/midgard.xml @@ -186,6 +186,14 @@ + + + + + + + + @@ -637,6 +645,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -661,6 +700,10 @@ + + + + @@ -760,6 +803,206 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -781,4 +1024,21 @@ + + + + + + + + + +
+
+
+
+
+
+
+ diff --git a/src/panfrost/lib/pan_format.c b/src/panfrost/lib/pan_format.c index 24e32a41fc8..7aae9806cf8 100644 --- a/src/panfrost/lib/pan_format.c +++ b/src/panfrost/lib/pan_format.c @@ -408,3 +408,21 @@ panfrost_format_to_bifrost_blend(const struct util_format_description *desc) return format; } } + +enum mali_z_internal_format +panfrost_get_z_internal_format(enum pipe_format fmt) +{ + switch (fmt) { + case PIPE_FORMAT_Z16_UNORM: + case PIPE_FORMAT_Z16_UNORM_S8_UINT: + return MALI_Z_INTERNAL_FORMAT_D16; + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + case PIPE_FORMAT_Z24X8_UNORM: + return MALI_Z_INTERNAL_FORMAT_D24; + case PIPE_FORMAT_Z32_FLOAT: + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + return MALI_Z_INTERNAL_FORMAT_D32; + default: + unreachable("Unsupported depth/stencil format."); + } +} diff --git a/src/panfrost/lib/pan_texture.h b/src/panfrost/lib/pan_texture.h index 3765836385d..852c103cabf 100644 --- a/src/panfrost/lib/pan_texture.h +++ b/src/panfrost/lib/pan_texture.h @@ -147,6 +147,9 @@ extern struct panfrost_format panfrost_pipe_format_table[PIPE_FORMAT_COUNT]; bool panfrost_is_z24s8_variant(enum pipe_format fmt); +enum mali_z_internal_format +panfrost_get_z_internal_format(enum pipe_format fmt); + unsigned panfrost_translate_swizzle_4(const unsigned char swizzle[4]);