From 9dd9ebe9c58ceb9cfee59114b640410d00edfbca Mon Sep 17 00:00:00 2001 From: Christian Gmeiner Date: Tue, 15 Jul 2025 12:21:00 +0200 Subject: [PATCH] etnaviv: Implement 128-bit format emulation using dual 64-bit layout The Vivante GPUs don't natively support 128-bit formats like R32G32B32A32_FLOAT. This patch implements emulation by calculating the memory layout as if these were 64-bit formats, but doubling the allocation size to store both halves of the 128-bit data. For 128-bit formats, we: - Calculate stride and layer_stride using the 64-bit equivalent format - Double the mip level size to accommodate both 64-bit halves - Use translate_format_128bit_to_64bit() to map formats like R32G32B32A32_FLOAT -> R32G32_FLOAT This creates a memory layout where each mip level contains the 128-bit data organized as two consecutive 64-bit portions. Signed-off-by: Christian Gmeiner Part-of: --- src/gallium/drivers/etnaviv/etnaviv_resource.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c b/src/gallium/drivers/etnaviv/etnaviv_resource.c index d15183a9056..703d8e449ec 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_resource.c +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c @@ -309,6 +309,7 @@ setup_miptree(struct etna_resource *rsc, unsigned paddingX, unsigned paddingY, unsigned msaa_xscale, unsigned msaa_yscale) { struct pipe_resource *prsc = &rsc->base; + enum pipe_format fmt = translate_format_128bit_to_64bit(prsc->format); unsigned level, size = 0; unsigned width = prsc->width0; unsigned height = prsc->height0; @@ -322,11 +323,14 @@ setup_miptree(struct etna_resource *rsc, unsigned paddingX, unsigned paddingY, mip->depth = depth; mip->padded_width = align(width * msaa_xscale, paddingX); mip->padded_height = align(height * msaa_yscale, paddingY); - mip->stride = util_format_get_stride(prsc->format, mip->padded_width); + mip->stride = util_format_get_stride(fmt, mip->padded_width); mip->offset = size; - mip->layer_stride = mip->stride * util_format_get_nblocksy(prsc->format, mip->padded_height); + mip->layer_stride = mip->stride * util_format_get_nblocksy(fmt, mip->padded_height); mip->size = prsc->array_size * mip->layer_stride; + if (format_is_128bit(prsc->format)) + mip->size *= 2; + /* align levels to 64 bytes to be able to render to them */ size += align(mip->size, ETNA_PE_ALIGNMENT) * depth;