struct lima_context_framebuffer *fb = &ctx->framebuffer;
struct lima_resource *res = lima_resource(fb->base.cbufs[0]->texture);
int level = fb->base.cbufs[0]->u.tex.level;
+ unsigned layer = fb->base.cbufs[0]->u.tex.first_layer;
uint32_t format = lima_format_get_pixel(fb->base.cbufs[0]->format);
bool swap_channels = lima_format_get_swap_rb(fb->base.cbufs[0]->format);
struct lima_pp_wb_reg *wb = (void *)wb_reg;
wb[wb_idx].type = 0x02; /* 2 for color buffer */
- wb[wb_idx].address = res->bo->va + res->levels[level].offset;
+ wb[wb_idx].address = res->bo->va + res->levels[level].offset + layer * res->levels[level].layer_stride;
wb[wb_idx].pixel_format = format;
if (res->tiled) {
wb[wb_idx].pixel_layout = 0x2;
res->levels[level].width = aligned_width;
res->levels[level].stride = stride;
res->levels[level].offset = size;
+ res->levels[level].layer_stride = util_format_get_stride(pres->format, align(width, 16)) * align(height, 16);
/* The start address of each level <= 10 must be 64-aligned
* in order to be able to pass the addresses
trans->staging = malloc(ptrans->stride * ptrans->box.height * ptrans->box.depth);
- if (usage & PIPE_TRANSFER_READ)
- panfrost_load_tiled_image(trans->staging, bo->map + res->levels[level].offset,
- &ptrans->box,
- ptrans->stride,
- res->levels[level].stride,
- util_format_get_blocksize(pres->format));
+ if (usage & PIPE_TRANSFER_READ) {
+ unsigned i;
+ for (i = 0; i < ptrans->box.depth; i++)
+ panfrost_load_tiled_image(
+ trans->staging + i * ptrans->stride * ptrans->box.height,
+ bo->map + res->levels[level].offset + (i + box->z) * res->levels[level].layer_stride,
+ &ptrans->box,
+ ptrans->stride,
+ res->levels[level].stride,
+ util_format_get_blocksize(pres->format));
+ }
return trans->staging;
} else {
ptrans->stride = res->levels[level].stride;
- ptrans->layer_stride = ptrans->stride * box->height;
+ ptrans->layer_stride = res->levels[level].layer_stride;
return bo->map + res->levels[level].offset +
- box->z * ptrans->layer_stride +
+ box->z * res->levels[level].layer_stride +
box->y / util_format_get_blockheight(pres->format) * ptrans->stride +
box->x / util_format_get_blockwidth(pres->format) *
util_format_get_blocksize(pres->format);
if (trans->staging) {
pres = &res->base;
- if (ptrans->usage & PIPE_TRANSFER_WRITE)
- panfrost_store_tiled_image(bo->map + res->levels[ptrans->level].offset, trans->staging,
- &ptrans->box,
- res->levels[ptrans->level].stride,
- ptrans->stride,
- util_format_get_blocksize(pres->format));
+ if (ptrans->usage & PIPE_TRANSFER_WRITE) {
+ unsigned i;
+ for (i = 0; i < ptrans->box.depth; i++)
+ panfrost_store_tiled_image(
+ bo->map + res->levels[ptrans->level].offset + (i + ptrans->box.z) * res->levels[ptrans->level].layer_stride,
+ trans->staging + i * ptrans->stride * ptrans->box.height,
+ &ptrans->box,
+ res->levels[ptrans->level].stride,
+ ptrans->stride,
+ util_format_get_blocksize(pres->format));
+ }
free(trans->staging);
}