From: Boris Brezillon Date: Thu, 17 Dec 2020 11:12:28 +0000 (+0100) Subject: panfrost: Add a pan_image_layout object X-Git-Tag: upstream/21.0.0~814 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4dd7991422ce06bc56e9adb82bca3b5c34c59a95;p=platform%2Fupstream%2Fmesa.git panfrost: Add a pan_image_layout object Group the slices, dimension, modifier and array stride in a an object representing the image layout. This way we shrink the number of arguments passed to various pan_texture helpers and simplifies some of the logic along the way. Signed-off-by: Boris Brezillon Reviewed-by: Alyssa Rosenzweig Part-of: --- diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index 0cd5247..c7d558d 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -1042,7 +1042,7 @@ panfrost_update_sampler_view(struct panfrost_sampler_view *view, { struct panfrost_resource *rsrc = pan_resource(view->base.texture); if (view->texture_bo != rsrc->bo->ptr.gpu || - view->modifier != rsrc->modifier) { + view->modifier != rsrc->layout.modifier) { panfrost_bo_unreference(view->bo); panfrost_create_sampler_view_bo(view, pctx, &rsrc->base); } diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 04f048f..70dc76e 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -1011,7 +1011,7 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so, } so->texture_bo = prsrc->bo->ptr.gpu; - so->modifier = prsrc->modifier; + so->modifier = prsrc->layout.modifier; unsigned char user_swizzle[4] = { so->base.swizzle_r, @@ -1048,7 +1048,8 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so, so->base.u.tex.first_layer, so->base.u.tex.last_layer, texture->nr_samples, - type, prsrc->modifier); + type, + prsrc->layout.modifier); so->bo = panfrost_bo_create(device, size, 0); @@ -1060,20 +1061,17 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so, payload.gpu += MALI_MIDGARD_TEXTURE_LENGTH; } - panfrost_new_texture(device, tex, + panfrost_new_texture(device, &prsrc->layout, tex, texture->width0, texture->height0, depth, array_size, - format, - type, prsrc->modifier, + format, type, so->base.u.tex.first_level, so->base.u.tex.last_level, so->base.u.tex.first_layer, so->base.u.tex.last_layer, texture->nr_samples, - prsrc->cubemap_stride, panfrost_translate_swizzle_4(user_swizzle), - prsrc->bo->ptr.gpu, - prsrc->slices, &payload); + prsrc->bo->ptr.gpu, &payload); } static struct pipe_sampler_view * diff --git a/src/gallium/drivers/panfrost/pan_fragment.c b/src/gallium/drivers/panfrost/pan_fragment.c index af97b18..0a6a026 100644 --- a/src/gallium/drivers/panfrost/pan_fragment.c +++ b/src/gallium/drivers/panfrost/pan_fragment.c @@ -42,7 +42,7 @@ panfrost_initialize_surface( unsigned level = surf->u.tex.level; struct panfrost_resource *rsrc = pan_resource(surf->texture); - rsrc->slices[level].initialized = true; + rsrc->layout.slices[level].initialized = true; } /* Generate a fragment job. This should be called once per frame. (According to diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c index 3304c46..301ce45 100644 --- a/src/gallium/drivers/panfrost/pan_job.c +++ b/src/gallium/drivers/panfrost/pan_job.c @@ -759,7 +759,7 @@ panfrost_load_surface(struct panfrost_batch *batch, struct pipe_surface *surf, u struct panfrost_resource *rsrc = pan_resource(surf->texture); unsigned level = surf->u.tex.level; - if (!rsrc->slices[level].initialized) + if (!rsrc->layout.slices[level].initialized) return; if (!rsrc->damage.inverted_len) @@ -808,16 +808,14 @@ panfrost_load_surface(struct panfrost_batch *batch, struct pipe_surface *surf, u .depth0 = rsrc->base.depth0, .format = format, .dim = dim, - .modifier = rsrc->modifier, .array_size = rsrc->base.array_size, .first_level = level, .last_level = level, .first_layer = surf->u.tex.first_layer, .last_layer = surf->u.tex.last_layer, .nr_samples = rsrc->base.nr_samples, - .cubemap_stride = rsrc->cubemap_stride, .bo = rsrc->bo, - .slices = rsrc->slices + .layout = &rsrc->layout, }; mali_ptr blend_shader = 0; diff --git a/src/gallium/drivers/panfrost/pan_mfbd.c b/src/gallium/drivers/panfrost/pan_mfbd.c index 5931025..83bd537 100644 --- a/src/gallium/drivers/panfrost/pan_mfbd.c +++ b/src/gallium/drivers/panfrost/pan_mfbd.c @@ -134,12 +134,12 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf, unsigned level = surf->u.tex.level; unsigned first_layer = surf->u.tex.first_layer; assert(surf->u.tex.last_layer == first_layer); - int row_stride = rsrc->slices[level].row_stride; + int row_stride = rsrc->layout.slices[level].row_stride; /* Only set layer_stride for layered MSAA rendering */ unsigned nr_samples = surf->texture->nr_samples; - unsigned layer_stride = (nr_samples > 1) ? rsrc->slices[level].surface_stride : 0; + unsigned layer_stride = (nr_samples > 1) ? rsrc->layout.slices[level].surface_stride : 0; mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0); if (layer_stride) @@ -151,7 +151,7 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf, panfrost_mfbd_rt_init_format(surf, rt); - if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) { + if (rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR) { if (version >= 7) rt->bifrost_v7.writeback_block_format = MALI_BLOCK_FORMAT_V7_LINEAR; else @@ -160,7 +160,7 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf, rt->rgb.base = base; rt->rgb.row_stride = row_stride; rt->rgb.surface_stride = layer_stride; - } else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { + } else if (rsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { if (version >= 7) rt->bifrost_v7.writeback_block_format = MALI_BLOCK_FORMAT_V7_TILED_U_INTERLEAVED; else @@ -169,13 +169,13 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf, rt->rgb.base = base; rt->rgb.row_stride = row_stride; rt->rgb.surface_stride = layer_stride; - } else if (drm_is_afbc(rsrc->modifier)) { + } else if (drm_is_afbc(rsrc->layout.modifier)) { if (version >= 7) rt->bifrost_v7.writeback_block_format = MALI_BLOCK_FORMAT_V7_AFBC; else rt->midgard.writeback_block_format = MALI_BLOCK_FORMAT_AFBC; - unsigned header_size = rsrc->slices[level].header_size; + unsigned header_size = rsrc->layout.slices[level].header_size; rt->afbc.header = base; rt->afbc.chunk_size = 9; @@ -184,7 +184,7 @@ panfrost_mfbd_rt_set_buf(struct pipe_surface *surf, if (!(dev->quirks & IS_BIFROST)) rt->midgard_afbc.sparse = true; - if (rsrc->modifier & AFBC_FORMAT_MOD_YTR) + if (rsrc->layout.modifier & AFBC_FORMAT_MOD_YTR) rt->afbc.yuv_transform_enable = true; /* TODO: The blob sets this to something nonzero, but it's not @@ -254,7 +254,7 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch, if (rsrc->checksummed) { unsigned level = c_surf->u.tex.level; - struct panfrost_slice *slice = &rsrc->slices[level]; + struct panfrost_slice *slice = &rsrc->layout.slices[level]; ext->crc_row_stride = slice->crc.stride; if (rsrc->checksum_bo) @@ -291,8 +291,8 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch, else ext->zs_msaa_v7 = nr_samples > 1 ? MALI_MSAA_LAYERED : MALI_MSAA_SINGLE; - if (drm_is_afbc(rsrc->modifier)) { - unsigned header_size = rsrc->slices[level].header_size; + if (drm_is_afbc(rsrc->layout.modifier)) { + unsigned header_size = rsrc->layout.slices[level].header_size; ext->zs_afbc_header = base; ext->zs_afbc_body = base + header_size; ext->zs_afbc_body_size = 0x1000; @@ -304,19 +304,18 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch, else ext->zs_block_format = MALI_BLOCK_FORMAT_AFBC; } else { - assert(rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED || - rsrc->modifier == DRM_FORMAT_MOD_LINEAR); + assert(rsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED || + rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR); /* TODO: Z32F(S8) support, which is always linear */ - int row_stride = rsrc->slices[level].row_stride; - - unsigned layer_stride = (nr_samples > 1) ? rsrc->slices[level].surface_stride : 0; - ext->zs_writeback_base = base; - ext->zs_writeback_row_stride = row_stride; - ext->zs_writeback_surface_stride = layer_stride; + ext->zs_writeback_row_stride = + rsrc->layout.slices[level].row_stride; + ext->zs_writeback_surface_stride = + (nr_samples > 1) ? + rsrc->layout.slices[level].surface_stride : 0; - if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) { + if (rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR) { if (version >= 7) ext->zs_block_format_v7 = MALI_BLOCK_FORMAT_V7_LINEAR; else @@ -358,12 +357,14 @@ panfrost_mfbd_zs_crc_ext_set_bufs(struct panfrost_batch *batch, } struct panfrost_resource *stencil = rsrc->separate_stencil; - struct panfrost_slice stencil_slice = stencil->slices[level]; - unsigned stencil_layer_stride = (nr_samples > 1) ? stencil_slice.surface_stride : 0; - - ext->s_writeback_base = panfrost_get_texture_address(stencil, level, first_layer, 0); - ext->s_writeback_row_stride = stencil_slice.row_stride; - ext->s_writeback_surface_stride = stencil_layer_stride; + struct panfrost_slice *stencil_slice = + &stencil->layout.slices[level]; + + ext->s_writeback_base = + panfrost_get_texture_address(stencil, level, first_layer, 0); + ext->s_writeback_row_stride = stencil_slice->row_stride; + ext->s_writeback_surface_stride = + (nr_samples > 1) ? stencil_slice->surface_stride : 0; break; default: unreachable("Unsupported depth/stencil format."); diff --git a/src/gallium/drivers/panfrost/pan_resource.c b/src/gallium/drivers/panfrost/pan_resource.c index b9a5fbf..be48365 100644 --- a/src/gallium/drivers/panfrost/pan_resource.c +++ b/src/gallium/drivers/panfrost/pan_resource.c @@ -96,36 +96,39 @@ panfrost_resource_from_handle(struct pipe_screen *pscreen, rsc->bo = panfrost_bo_import(dev, whandle->handle); rsc->internal_format = templat->format; - rsc->modifier = (whandle->modifier == DRM_FORMAT_MOD_INVALID) ? - DRM_FORMAT_MOD_LINEAR : whandle->modifier; + rsc->layout.modifier = (whandle->modifier == DRM_FORMAT_MOD_INVALID) ? + DRM_FORMAT_MOD_LINEAR : whandle->modifier; + rsc->layout.dim = panfrost_translate_texture_dimension(templat->target); rsc->modifier_constant = true; - rsc->slices[0].line_stride = whandle->stride; - rsc->slices[0].row_stride = whandle->stride; + rsc->layout.slices[0].line_stride = whandle->stride; + rsc->layout.slices[0].row_stride = whandle->stride; - if (rsc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED || - drm_is_afbc(rsc->modifier)) { - unsigned tile_h = panfrost_block_dim(rsc->modifier, false, 0); + if (rsc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED || + drm_is_afbc(rsc->layout.modifier)) { + unsigned tile_h = panfrost_block_dim(rsc->layout.modifier, false, 0); if (util_format_is_compressed(rsc->internal_format)) tile_h >>= 2; - rsc->slices[0].row_stride *= tile_h; + rsc->layout.slices[0].row_stride *= tile_h; } - rsc->slices[0].offset = whandle->offset; - rsc->slices[0].initialized = true; + rsc->layout.slices[0].offset = whandle->offset; + rsc->layout.slices[0].initialized = true; panfrost_resource_set_damage_region(NULL, &rsc->base, 0, NULL); if (dev->quirks & IS_BIFROST && templat->bind & PIPE_BIND_RENDER_TARGET) { - unsigned size = panfrost_compute_checksum_size( - &rsc->slices[0], templat->width0, templat->height0); + unsigned size = + panfrost_compute_checksum_size(&rsc->layout.slices[0], + templat->width0, + templat->height0); rsc->checksum_bo = panfrost_bo_create(dev, size, 0); rsc->checksummed = true; } if (drm_is_afbc(whandle->modifier)) { - rsc->slices[0].header_size = + rsc->layout.slices[0].header_size = panfrost_afbc_header_size(templat->width0, templat->height0); } @@ -149,7 +152,7 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen, struct panfrost_resource *rsrc = (struct panfrost_resource *) pt; struct renderonly_scanout *scanout = rsrc->scanout; - handle->modifier = rsrc->modifier; + handle->modifier = rsrc->layout.modifier; rsrc->modifier_constant = true; if (handle->type == WINSYS_HANDLE_TYPE_SHARED) { @@ -159,8 +162,8 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen, return true; handle->handle = rsrc->bo->gem_handle; - handle->stride = rsrc->slices[0].line_stride; - handle->offset = rsrc->slices[0].offset; + handle->stride = rsrc->layout.slices[0].line_stride; + handle->offset = rsrc->layout.slices[0].offset; return TRUE; } else if (handle->type == WINSYS_HANDLE_TYPE_FD) { if (scanout) { @@ -184,8 +187,8 @@ panfrost_resource_get_handle(struct pipe_screen *pscreen, return false; handle->handle = fd; - handle->stride = rsrc->slices[0].line_stride; - handle->offset = rsrc->slices[0].offset; + handle->stride = rsrc->layout.slices[0].line_stride; + handle->offset = rsrc->layout.slices[0].offset; return true; } } @@ -311,7 +314,7 @@ panfrost_create_scanout_res(struct pipe_screen *screen, /* Setup the mip tree given a particular modifier, possibly with checksumming */ static void -panfrost_setup_slices(struct panfrost_device *dev, +panfrost_setup_layout(struct panfrost_device *dev, struct panfrost_resource *pres, size_t *bo_size) { @@ -343,24 +346,23 @@ panfrost_setup_slices(struct panfrost_device *dev, bool renderable = res->bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL) && res->target != PIPE_BUFFER; - bool afbc = drm_is_afbc(pres->modifier); - bool tiled = pres->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED; - bool linear = pres->modifier == DRM_FORMAT_MOD_LINEAR; + bool afbc = drm_is_afbc(pres->layout.modifier); + bool tiled = pres->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED; + bool linear = pres->layout.modifier == DRM_FORMAT_MOD_LINEAR; bool should_align = renderable || tiled || afbc; unsigned offset = 0; - unsigned size_2d = 0; unsigned tile_h = 1, tile_w = 1, tile_shift = 0; if (tiled || afbc) { - tile_w = panfrost_block_dim(pres->modifier, true, 0); - tile_h = panfrost_block_dim(pres->modifier, false, 0); + tile_w = panfrost_block_dim(pres->layout.modifier, true, 0); + tile_h = panfrost_block_dim(pres->layout.modifier, false, 0); if (util_format_is_compressed(pres->internal_format)) tile_shift = 2; } for (unsigned l = 0; l <= res->last_level; ++l) { - struct panfrost_slice *slice = &pres->slices[l]; + struct panfrost_slice *slice = &pres->layout.slices[l]; unsigned effective_width = width; unsigned effective_height = height; @@ -399,11 +401,6 @@ panfrost_setup_slices(struct panfrost_device *dev, slice->surface_stride = slice_one_size; - /* Report 2D size for 3D texturing */ - - if (l == 0) - size_2d = slice_one_size; - /* Compute AFBC sizes if necessary */ if (afbc) { slice->header_size = @@ -431,20 +428,10 @@ panfrost_setup_slices(struct panfrost_device *dev, assert(res->array_size); - if (res->target != PIPE_TEXTURE_3D) { - /* Arrays and cubemaps have the entire miptree duplicated */ - - pres->cubemap_stride = ALIGN_POT(offset, 64); - if (bo_size) - *bo_size = ALIGN_POT(pres->cubemap_stride * res->array_size, 4096); - } else { - /* 3D strides across the 2D layers */ - assert(res->array_size == 1); - - pres->cubemap_stride = size_2d; - if (bo_size) - *bo_size = ALIGN_POT(offset, 4096); - } + /* Arrays and cubemaps have the entire miptree duplicated */ + pres->layout.array_stride = ALIGN_POT(offset, 64); + if (bo_size) + *bo_size = ALIGN_POT(pres->layout.array_stride * res->array_size, 4096); } /* Based on the usage, determine if it makes sense to use u-inteleaved tiling. @@ -550,16 +537,16 @@ static void panfrost_resource_setup(struct panfrost_device *dev, struct panfrost_resource *pres, size_t *bo_size, uint64_t modifier) { - pres->modifier = (modifier != DRM_FORMAT_MOD_INVALID) ? modifier : + pres->layout.modifier = (modifier != DRM_FORMAT_MOD_INVALID) ? modifier : panfrost_best_modifier(dev, pres); pres->checksummed = (pres->base.bind & PIPE_BIND_RENDER_TARGET); /* We can only switch tiled->linear if the resource isn't already * linear and if we control the modifier */ - pres->modifier_constant = !((pres->modifier != DRM_FORMAT_MOD_LINEAR) + pres->modifier_constant = !((pres->layout.modifier != DRM_FORMAT_MOD_LINEAR) && (modifier == DRM_FORMAT_MOD_INVALID)); - panfrost_setup_slices(dev, pres, bo_size); + panfrost_setup_layout(dev, pres, bo_size); } void @@ -639,6 +626,7 @@ panfrost_resource_create_with_modifier(struct pipe_screen *screen, so->base = *template; so->base.screen = screen; so->internal_format = template->format; + so->layout.dim = panfrost_translate_texture_dimension(template->target); pipe_reference_init(&so->base.reference, 1); @@ -814,7 +802,7 @@ panfrost_ptr_map(struct pipe_context *pctx, struct panfrost_bo *bo = rsrc->bo; /* Can't map tiled/compressed directly */ - if ((usage & PIPE_MAP_DIRECTLY) && rsrc->modifier != DRM_FORMAT_MOD_LINEAR) + if ((usage & PIPE_MAP_DIRECTLY) && rsrc->layout.modifier != DRM_FORMAT_MOD_LINEAR) return NULL; struct panfrost_transfer *transfer = rzalloc(pctx, struct panfrost_transfer); @@ -826,9 +814,9 @@ panfrost_ptr_map(struct pipe_context *pctx, *out_transfer = &transfer->base; /* We don't have s/w routines for AFBC, so use a staging texture */ - if (drm_is_afbc(rsrc->modifier)) { + if (drm_is_afbc(rsrc->layout.modifier)) { struct panfrost_resource *staging = pan_alloc_staging(ctx, rsrc, level, box); - transfer->base.stride = staging->slices[0].line_stride; + transfer->base.stride = staging->layout.slices[0].line_stride; transfer->base.layer_stride = transfer->base.stride * box->height; transfer->staging.rsrc = &staging->base; @@ -845,7 +833,7 @@ panfrost_ptr_map(struct pipe_context *pctx, * from a pending batch XXX */ panfrost_flush_batches_accessing_bo(ctx, rsrc->bo, true); - if ((usage & PIPE_MAP_READ) && rsrc->slices[level].initialized) { + if ((usage & PIPE_MAP_READ) && rsrc->layout.slices[level].initialized) { pan_blit_to_staging(pctx, transfer); panfrost_flush_batches_accessing_bo(ctx, staging->bo, true); panfrost_bo_wait(staging->bo, INT64_MAX, false); @@ -932,25 +920,25 @@ panfrost_ptr_map(struct pipe_context *pctx, } } - if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { + if (rsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { transfer->base.stride = box->width * bytes_per_pixel; transfer->base.layer_stride = transfer->base.stride * box->height; transfer->map = ralloc_size(transfer, transfer->base.layer_stride * box->depth); assert(box->depth == 1); - if ((usage & PIPE_MAP_READ) && rsrc->slices[level].initialized) { + if ((usage & PIPE_MAP_READ) && rsrc->layout.slices[level].initialized) { panfrost_load_tiled_image( transfer->map, - bo->ptr.cpu + rsrc->slices[level].offset, + bo->ptr.cpu + rsrc->layout.slices[level].offset, box->x, box->y, box->width, box->height, transfer->base.stride, - rsrc->slices[level].line_stride, + rsrc->layout.slices[level].line_stride, rsrc->internal_format); } return transfer->map; } else { - assert (rsrc->modifier == DRM_FORMAT_MOD_LINEAR); + assert (rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR); /* Direct, persistent writes create holes in time for * caching... I don't know if this is actually possible but we @@ -961,23 +949,22 @@ panfrost_ptr_map(struct pipe_context *pctx, if ((usage & dpw) == dpw && rsrc->index_cache) return NULL; - transfer->base.stride = rsrc->slices[level].line_stride; - transfer->base.layer_stride = panfrost_get_layer_stride( - rsrc->slices, rsrc->base.target == PIPE_TEXTURE_3D, - rsrc->cubemap_stride, level); + transfer->base.stride = rsrc->layout.slices[level].line_stride; + transfer->base.layer_stride = + panfrost_get_layer_stride(&rsrc->layout, level); /* By mapping direct-write, we're implicitly already * initialized (maybe), so be conservative */ if (usage & PIPE_MAP_WRITE) { - rsrc->slices[level].initialized = true; + rsrc->layout.slices[level].initialized = true; panfrost_minmax_cache_invalidate(rsrc->index_cache, &transfer->base); } return bo->ptr.cpu - + rsrc->slices[level].offset + + rsrc->layout.slices[level].offset + transfer->base.box.z * transfer->base.layer_stride - + transfer->base.box.y * rsrc->slices[level].line_stride + + transfer->base.box.y * rsrc->layout.slices[level].line_stride + transfer->base.box.x * bytes_per_pixel; } } @@ -1050,9 +1037,9 @@ panfrost_ptr_unmap(struct pipe_context *pctx, struct panfrost_bo *bo = prsrc->bo; if (transfer->usage & PIPE_MAP_WRITE) { - prsrc->slices[transfer->level].initialized = true; + prsrc->layout.slices[transfer->level].initialized = true; - if (prsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { + if (prsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { assert(transfer->box.depth == 1); if (panfrost_should_linear_convert(prsrc, transfer)) { @@ -1066,9 +1053,9 @@ panfrost_ptr_unmap(struct pipe_context *pctx, } util_copy_rect( - bo->ptr.cpu + prsrc->slices[0].offset, + bo->ptr.cpu + prsrc->layout.slices[0].offset, prsrc->base.format, - prsrc->slices[0].line_stride, + prsrc->layout.slices[0].line_stride, 0, 0, transfer->box.width, transfer->box.height, @@ -1077,11 +1064,11 @@ panfrost_ptr_unmap(struct pipe_context *pctx, 0, 0); } else { panfrost_store_tiled_image( - bo->ptr.cpu + prsrc->slices[transfer->level].offset, + bo->ptr.cpu + prsrc->layout.slices[transfer->level].offset, trans->map, transfer->box.x, transfer->box.y, transfer->box.width, transfer->box.height, - prsrc->slices[transfer->level].line_stride, + prsrc->layout.slices[transfer->level].line_stride, transfer->stride, prsrc->internal_format); } @@ -1116,7 +1103,7 @@ panfrost_ptr_flush_region(struct pipe_context *pctx, transfer->box.x + box->x + box->width); } else { unsigned level = transfer->level; - rsc->slices[level].initialized = true; + rsc->layout.slices[level].initialized = true; } } @@ -1151,7 +1138,7 @@ panfrost_generate_mipmap( assert(rsrc->bo); for (unsigned l = base_level + 1; l <= last_level; ++l) - rsrc->slices[l].initialized = false; + rsrc->layout.slices[l].initialized = false; /* Beyond that, we just delegate the hard stuff. */ @@ -1167,15 +1154,16 @@ panfrost_generate_mipmap( /* Computes the address to a texture at a particular slice */ mali_ptr -panfrost_get_texture_address( - struct panfrost_resource *rsrc, - unsigned level, unsigned face, unsigned sample) +panfrost_get_texture_address(struct panfrost_resource *rsrc, + unsigned level, unsigned layer, + unsigned sample) { bool is_3d = rsrc->base.target == PIPE_TEXTURE_3D; + unsigned array_idx = is_3d ? 0 : layer; + unsigned surface_idx = is_3d ? layer : sample; return rsrc->bo->ptr.gpu + - panfrost_texture_offset(rsrc->slices, is_3d, - rsrc->cubemap_stride, - level, face, sample); + panfrost_texture_offset(&rsrc->layout, level, + array_idx, surface_idx); } static void diff --git a/src/gallium/drivers/panfrost/pan_resource.h b/src/gallium/drivers/panfrost/pan_resource.h index 183af68..6a8104d 100644 --- a/src/gallium/drivers/panfrost/pan_resource.h +++ b/src/gallium/drivers/panfrost/pan_resource.h @@ -52,14 +52,8 @@ struct panfrost_resource { struct util_range valid_buffer_range; - /* Description of the mip levels */ - struct panfrost_slice slices[MAX_MIP_LEVELS]; - - /* Distance from tree to tree */ - unsigned cubemap_stride; - - /* DRM fourcc code: linear, 16x16 u-interleaved, AFBC */ - uint64_t modifier; + /* Description of the resource layout */ + struct pan_image_layout layout; /* Whether the modifier can be changed */ bool modifier_constant; @@ -101,9 +95,9 @@ pan_transfer(struct pipe_transfer *p) } mali_ptr -panfrost_get_texture_address( - struct panfrost_resource *rsrc, - unsigned level, unsigned face, unsigned sample); +panfrost_get_texture_address(struct panfrost_resource *rsrc, + unsigned level, unsigned layer, + unsigned sample); void panfrost_resource_screen_init(struct pipe_screen *screen); diff --git a/src/gallium/drivers/panfrost/pan_sfbd.c b/src/gallium/drivers/panfrost/pan_sfbd.c index 3fcaf3c..3d378f3 100644 --- a/src/gallium/drivers/panfrost/pan_sfbd.c +++ b/src/gallium/drivers/panfrost/pan_sfbd.c @@ -84,7 +84,7 @@ panfrost_sfbd_set_cbuf( unsigned level = surf->u.tex.level; unsigned first_layer = surf->u.tex.first_layer; assert(surf->u.tex.last_layer == first_layer); - signed row_stride = rsrc->slices[level].row_stride; + signed row_stride = rsrc->layout.slices[level].row_stride; mali_ptr base = panfrost_get_texture_address(rsrc, level, first_layer, 0); @@ -94,9 +94,9 @@ panfrost_sfbd_set_cbuf( fb->color_writeback.base = base; fb->color_writeback.row_stride = row_stride; - if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) + if (rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR) fb->color_block_format = MALI_BLOCK_FORMAT_LINEAR; - else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { + else if (rsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { fb->color_block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED; } else { fprintf(stderr, "Invalid render modifier\n"); @@ -114,12 +114,12 @@ panfrost_sfbd_set_zsbuf( unsigned level = surf->u.tex.level; assert(surf->u.tex.first_layer == 0); - fb->zs_writeback.base = rsrc->bo->ptr.gpu + rsrc->slices[level].offset; - fb->zs_writeback.row_stride = rsrc->slices[level].row_stride; + fb->zs_writeback.base = rsrc->bo->ptr.gpu + rsrc->layout.slices[level].offset; + fb->zs_writeback.row_stride = rsrc->layout.slices[level].row_stride; - if (rsrc->modifier == DRM_FORMAT_MOD_LINEAR) + if (rsrc->layout.modifier == DRM_FORMAT_MOD_LINEAR) fb->zs_block_format = MALI_BLOCK_FORMAT_LINEAR; - else if (rsrc->modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { + else if (rsrc->layout.modifier == DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED) { fb->zs_block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED; } else { fprintf(stderr, "Invalid render modifier\n"); @@ -230,7 +230,7 @@ panfrost_sfbd_fragment(struct panfrost_batch *batch, bool has_draws) if (rsrc->checksummed) { unsigned level = surf->u.tex.level; - struct panfrost_slice *slice = &rsrc->slices[level]; + struct panfrost_slice *slice = &rsrc->layout.slices[level]; params.crc_buffer.row_stride = slice->crc.stride; params.crc_buffer.base = bo->ptr.gpu + slice->crc.offset; diff --git a/src/panfrost/lib/pan_blit.c b/src/panfrost/lib/pan_blit.c index e796d95..e3c7c2b 100644 --- a/src/panfrost/lib/pan_blit.c +++ b/src/panfrost/lib/pan_blit.c @@ -316,21 +316,20 @@ midgard_load_emit_texture(struct pan_pool *pool, struct MALI_DRAW *draw, * itself is for a 2D texture with array size 1 even for 3D/array * textures, removing the need to separately key the blit shaders for * 2D and 3D variants */ - panfrost_new_texture(pool->dev, texture.cpu, - image->width0, image->height0, - MAX2(image->nr_samples, 1), 1, - image->format, MALI_TEXTURE_DIMENSION_2D, - image->modifier, - image->first_level, image->last_level, - 0, 0, - image->nr_samples, - 0, - PAN_V6_SWIZZLE(R, G, B, A), - image->bo->ptr.gpu + image->first_layer * - panfrost_get_layer_stride(image->slices, - image->dim == MALI_TEXTURE_DIMENSION_3D, - image->cubemap_stride, image->first_level), - image->slices, &payload); + + unsigned offset = + image->first_layer * + panfrost_get_layer_stride(image->layout, image->first_level); + + panfrost_new_texture(pool->dev, image->layout, texture.cpu, + image->width0, image->height0, + MAX2(image->nr_samples, 1), 1, + image->format, MALI_TEXTURE_DIMENSION_2D, + image->first_level, image->last_level, + 0, 0, + image->nr_samples, + PAN_V6_SWIZZLE(R, G, B, A), + image->bo->ptr.gpu + offset, &payload); pan_pack(sampler.cpu, MIDGARD_SAMPLER, cfg) cfg.normalized_coordinates = false; @@ -492,21 +491,19 @@ bifrost_load_emit_texture(struct pan_pool *pool, struct MALI_DRAW *draw, .gpu = texture.gpu + MALI_BIFROST_TEXTURE_LENGTH, }; - panfrost_new_texture(pool->dev, (void *)texture.cpu, + unsigned offset = + image->first_layer * + panfrost_get_layer_stride(image->layout, image->first_level); + + panfrost_new_texture(pool->dev, image->layout, texture.cpu, image->width0, image->height0, MAX2(image->nr_samples, 1), 1, image->format, MALI_TEXTURE_DIMENSION_2D, - image->modifier, image->first_level, image->last_level, 0, 0, image->nr_samples, - 0, PAN_V6_SWIZZLE(R, G, B, A), - image->bo->ptr.gpu + image->first_layer * - panfrost_get_layer_stride(image->slices, - image->dim == MALI_TEXTURE_DIMENSION_3D, - image->cubemap_stride, image->first_level), - image->slices, &payload); + image->bo->ptr.gpu + offset, &payload); pan_pack(sampler.cpu, BIFROST_SAMPLER, cfg) { cfg.seamless_cube_map = false; diff --git a/src/panfrost/lib/pan_texture.c b/src/panfrost/lib/pan_texture.c index be487f2..3e39050 100644 --- a/src/panfrost/lib/pan_texture.c +++ b/src/panfrost/lib/pan_texture.c @@ -79,9 +79,8 @@ panfrost_modifier_to_layout(uint64_t modifier) static bool panfrost_needs_explicit_stride(const struct panfrost_device *dev, - uint64_t modifier, + const struct pan_image_layout *layout, enum pipe_format format, - struct panfrost_slice *slices, uint16_t width, unsigned first_level, unsigned last_level) @@ -90,14 +89,14 @@ panfrost_needs_explicit_stride(const struct panfrost_device *dev, if (dev->quirks & IS_BIFROST) return true; - if (modifier != DRM_FORMAT_MOD_LINEAR) + if (layout->modifier != DRM_FORMAT_MOD_LINEAR) return false; unsigned bytes_per_block = util_format_get_blocksize(format); unsigned block_w = util_format_get_blockwidth(format); for (unsigned l = first_level; l <= last_level; ++l) { - unsigned actual = slices[l].line_stride; + unsigned actual = layout->slices[l].line_stride; unsigned expected = DIV_ROUND_UP(u_minify(width, l), block_w) * bytes_per_block; @@ -269,34 +268,22 @@ panfrost_block_dim(uint64_t modifier, bool width, unsigned plane) } static uint64_t -panfrost_get_surface_strides(struct panfrost_slice *slices, - const struct util_format_description *desc, - enum mali_texture_dimension dim, - uint64_t modifier, - unsigned width, unsigned height, - unsigned l, unsigned cube_stride) +panfrost_get_surface_strides(const struct pan_image_layout *layout, + unsigned l) { - bool is_3d = dim == MALI_TEXTURE_DIMENSION_3D; - - unsigned line_stride = slices[l].row_stride; - unsigned layer_stride = - panfrost_get_layer_stride(slices, is_3d, cube_stride, l); - - return ((uint64_t)layer_stride << 32) | line_stride; + return ((uint64_t)layout->slices[l].surface_stride << 32) | + layout->slices[l].row_stride; } static mali_ptr -panfrost_get_surface_pointer(mali_ptr base, struct panfrost_slice *slices, +panfrost_get_surface_pointer(const struct pan_image_layout *layout, enum mali_texture_dimension dim, - unsigned l, unsigned w, unsigned f, unsigned s, - unsigned cube_stride) + mali_ptr base, + unsigned l, unsigned w, unsigned f, unsigned s) { unsigned face_mult = dim == MALI_TEXTURE_DIMENSION_CUBE ? 6 : 1; - bool is_3d = dim == MALI_TEXTURE_DIMENSION_3D; - return base + - panfrost_texture_offset(slices, is_3d, cube_stride, - l, w * face_mult + f, s); + return base + panfrost_texture_offset(layout, l, w * face_mult + f, s); } struct panfrost_surface_iter { @@ -357,28 +344,27 @@ panfrost_surface_iter_next(const struct panfrost_device *dev, static void panfrost_emit_texture_payload(const struct panfrost_device *dev, + const struct pan_image_layout *layout, mali_ptr *payload, const struct util_format_description *desc, enum mali_texture_dimension dim, - uint64_t modifier, - unsigned width, unsigned height, unsigned first_level, unsigned last_level, unsigned first_layer, unsigned last_layer, unsigned nr_samples, - unsigned cube_stride, bool manual_stride, - mali_ptr base, - struct panfrost_slice *slices) + mali_ptr base) { - base |= panfrost_compression_tag(dev, desc, dim, modifier); + base |= panfrost_compression_tag(dev, desc, dim, layout->modifier); /* Inject the addresses in, interleaving array indices, mip levels, * cube faces, and strides in that order */ unsigned first_face = 0, last_face = 0; - if (dim == MALI_TEXTURE_DIMENSION_CUBE) - panfrost_adjust_cube_dimensions(&first_face, &last_face, &first_layer, &last_layer); + if (dim == MALI_TEXTURE_DIMENSION_CUBE) { + panfrost_adjust_cube_dimensions(&first_face, &last_face, + &first_layer, &last_layer); + } nr_samples = MAX2(nr_samples, 1); @@ -391,36 +377,31 @@ panfrost_emit_texture_payload(const struct panfrost_device *dev, !panfrost_surface_iter_end(&iter); panfrost_surface_iter_next(dev, &iter)) { payload[idx++] = - panfrost_get_surface_pointer(base, slices, dim, + panfrost_get_surface_pointer(layout, dim, base, iter.level, iter.layer, - iter.face, iter.sample, - cube_stride); + iter.face, iter.sample); if (!manual_stride) continue; payload[idx++] = - panfrost_get_surface_strides(slices, desc, dim, - modifier, width, height, - iter.level, cube_stride); + panfrost_get_surface_strides(layout, iter.level); } } void panfrost_new_texture(const struct panfrost_device *dev, + const struct pan_image_layout *layout, void *out, uint16_t width, uint16_t height, uint16_t depth, uint16_t array_size, enum pipe_format format, enum mali_texture_dimension dim, - uint64_t modifier, unsigned first_level, unsigned last_level, unsigned first_layer, unsigned last_layer, unsigned nr_samples, - unsigned cube_stride, unsigned swizzle, mali_ptr base, - struct panfrost_slice *slices, const struct panfrost_ptr *payload) { const struct util_format_description *desc = @@ -428,22 +409,17 @@ panfrost_new_texture(const struct panfrost_device *dev, bool is_bifrost = dev->quirks & IS_BIFROST; bool manual_stride = - panfrost_needs_explicit_stride(dev, modifier, format, slices, - width, first_level, last_level); + panfrost_needs_explicit_stride(dev, layout, format, width, + first_level, last_level); - panfrost_emit_texture_payload(dev, + panfrost_emit_texture_payload(dev, layout, payload->cpu, - desc, - dim, - modifier, - width, height, + desc, dim, first_level, last_level, first_layer, last_layer, nr_samples, - cube_stride, manual_stride, - base, - slices); + base); if (is_bifrost) { pan_pack(out, BIFROST_TEXTURE, cfg) { @@ -456,7 +432,8 @@ panfrost_new_texture(const struct panfrost_device *dev, else cfg.sample_count = MAX2(nr_samples, 1); cfg.swizzle = swizzle; - cfg.texel_ordering = panfrost_modifier_to_layout(modifier); + cfg.texel_ordering = + panfrost_modifier_to_layout(layout->modifier); cfg.levels = last_level - first_level + 1; cfg.array_size = array_size; cfg.surfaces = payload->gpu; @@ -477,7 +454,8 @@ panfrost_new_texture(const struct panfrost_device *dev, cfg.array_size = array_size; cfg.format = panfrost_pipe_format_v6[format].hw; cfg.dimension = dim; - cfg.texel_ordering = panfrost_modifier_to_layout(modifier); + cfg.texel_ordering = + panfrost_modifier_to_layout(layout->modifier); cfg.manual_stride = manual_stride; cfg.levels = last_level - first_level + 1; cfg.swizzle = swizzle; @@ -511,17 +489,24 @@ panfrost_compute_checksum_size( } unsigned -panfrost_get_layer_stride(struct panfrost_slice *slices, bool is_3d, unsigned cube_stride, unsigned level) +panfrost_get_layer_stride(const struct pan_image_layout *layout, + unsigned level) { - return is_3d ? slices[level].surface_stride : cube_stride; + if (layout->dim == MALI_TEXTURE_DIMENSION_3D) + return layout->slices[level].surface_stride; + + return layout->array_stride; } /* Computes the offset into a texture at a particular level/face. Add to * the base address of a texture to get the address to that level/face */ unsigned -panfrost_texture_offset(struct panfrost_slice *slices, bool is_3d, unsigned cube_stride, unsigned level, unsigned face, unsigned sample) +panfrost_texture_offset(const struct pan_image_layout *layout, + unsigned level, unsigned array_idx, + unsigned surface_idx) { - unsigned layer_stride = panfrost_get_layer_stride(slices, is_3d, cube_stride, level); - return slices[level].offset + (face * layer_stride) + (sample * slices[level].surface_stride); + return layout->slices[level].offset + + (array_idx * layout->array_stride) + + (surface_idx * layout->slices[level].surface_stride); } diff --git a/src/panfrost/lib/pan_texture.h b/src/panfrost/lib/pan_texture.h index 9507e23..7def961 100644 --- a/src/panfrost/lib/pan_texture.h +++ b/src/panfrost/lib/pan_texture.h @@ -59,6 +59,13 @@ struct panfrost_slice { bool initialized; }; +struct pan_image_layout { + uint64_t modifier; + enum mali_texture_dimension dim; + struct panfrost_slice slices[MAX_MIP_LEVELS]; + unsigned array_stride; +}; + struct pan_image { /* Format and size */ uint16_t width0, height0, depth0, array_size; @@ -68,9 +75,7 @@ struct pan_image { unsigned first_layer, last_layer; unsigned nr_samples; struct panfrost_bo *bo; - struct panfrost_slice *slices; - unsigned cubemap_stride; - uint64_t modifier; + const struct pan_image_layout *layout; }; unsigned @@ -102,26 +107,27 @@ panfrost_estimate_texture_payload_size( void panfrost_new_texture(const struct panfrost_device *dev, + const struct pan_image_layout *layout, void *out, uint16_t width, uint16_t height, uint16_t depth, uint16_t array_size, enum pipe_format format, enum mali_texture_dimension dim, - uint64_t modifier, unsigned first_level, unsigned last_level, unsigned first_layer, unsigned last_layer, unsigned nr_samples, - unsigned cube_stride, unsigned swizzle, mali_ptr base, - struct panfrost_slice *slices, const struct panfrost_ptr *payload); unsigned -panfrost_get_layer_stride(struct panfrost_slice *slices, bool is_3d, unsigned cube_stride, unsigned level); +panfrost_get_layer_stride(const struct pan_image_layout *layout, + unsigned level); unsigned -panfrost_texture_offset(struct panfrost_slice *slices, bool is_3d, unsigned cube_stride, unsigned level, unsigned face, unsigned sample); +panfrost_texture_offset(const struct pan_image_layout *layout, + unsigned level, unsigned array_idx, + unsigned surface_idx); /* Formats */