{
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);
}
}
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,
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);
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 *
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
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)
.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;
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)
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
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
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;
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
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)
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;
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
}
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.");
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);
}
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) {
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) {
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;
}
}
/* 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)
{
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;
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 =
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.
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
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);
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);
*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;
* 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);
}
}
- 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
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;
}
}
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)) {
}
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,
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);
}
transfer->box.x + box->x + box->width);
} else {
unsigned level = transfer->level;
- rsc->slices[level].initialized = true;
+ rsc->layout.slices[level].initialized = true;
}
}
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. */
/* 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
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;
}
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);
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);
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");
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");
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;
* 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;
.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;
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)
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;
}
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 {
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);
!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 =
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) {
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;
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;
}
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);
}
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;
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
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 */