diff --git a/docs/features.txt b/docs/features.txt
index 66741b288ab..a0a2fddccd9 100644
--- a/docs/features.txt
+++ b/docs/features.txt
@@ -331,7 +331,7 @@ Khronos, ARB, and OES extensions that are not part of any OpenGL or OpenGL ES ve
GL_EXT_semaphore_win32 DONE (zink, d3d12)
GL_EXT_shader_group_vote DONE (all drivers that support GL_ARB_shader_group_vote)
GL_EXT_sRGB_write_control DONE (all drivers that support GLES 3.0+)
- GL_EXT_texture_compression_astc_decode_mode DONE (core only)
+ GL_EXT_texture_compression_astc_decode_mode DONE (panfrost)
GL_EXT_texture_norm16 DONE (freedreno, r600, radeonsi, nvc0i, softpipe, zink, iris, crocus)
GL_EXT_texture_sRGB_R8 DONE (all drivers that support GLES 3.0+)
GL_KHR_blend_equation_advanced_coherent DONE (freedreno/a6xx, panfrost, zink, asahi, iris/gen9+)
diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c
index 35b82c6ef7b..9c9484068e4 100644
--- a/src/gallium/drivers/panfrost/pan_cmdstream.c
+++ b/src/gallium/drivers/panfrost/pan_cmdstream.c
@@ -1606,9 +1606,10 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
payload.gpu += pan_size(TEXTURE);
}
+ const struct util_format_description *desc =
+ util_format_description(format);
+
if ((device->debug & PAN_DBG_YUV) && panfrost_format_is_yuv(format)) {
- const struct util_format_description *desc =
- util_format_description(format);
if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
iview.swizzle[2] = PIPE_SWIZZLE_1;
@@ -1618,6 +1619,11 @@ panfrost_create_sampler_view_bo(struct panfrost_sampler_view *so,
}
}
+ if (desc->layout == UTIL_FORMAT_LAYOUT_ASTC &&
+ so->base.astc_decode_format == PIPE_ASTC_DECODE_FORMAT_UNORM8) {
+ iview.astc.narrow = true;
+ }
+
GENX(panfrost_new_texture)(&iview, tex, &payload);
}
diff --git a/src/gallium/drivers/panfrost/pan_screen.c b/src/gallium/drivers/panfrost/pan_screen.c
index 8717a422053..ebc522fe815 100644
--- a/src/gallium/drivers/panfrost/pan_screen.c
+++ b/src/gallium/drivers/panfrost/pan_screen.c
@@ -366,6 +366,9 @@ panfrost_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_NATIVE_FENCE_FD:
return 1;
+ case PIPE_CAP_ASTC_DECODE_MODE:
+ return dev->arch >= 9 && (dev->compressed_formats & (1 << 30));
+
default:
return u_pipe_screen_get_param_defaults(screen, param);
}
diff --git a/src/panfrost/lib/genxml/v10.xml b/src/panfrost/lib/genxml/v10.xml
index 9411b9ebbee..e89f270ba1b 100644
--- a/src/panfrost/lib/genxml/v10.xml
+++ b/src/panfrost/lib/genxml/v10.xml
@@ -110,8 +110,8 @@
-
-
+
+
diff --git a/src/panfrost/lib/pan_format.c b/src/panfrost/lib/pan_format.c
index 0579f340a8e..f2379739f99 100644
--- a/src/panfrost/lib/pan_format.c
+++ b/src/panfrost/lib/pan_format.c
@@ -268,8 +268,8 @@ const struct panfrost_format GENX(panfrost_pipe_format)[PIPE_FORMAT_COUNT] = {
FMT(BPTC_RGBA_UNORM, RGBA8_UNORM, RGBA, L, _T__),
FMT(BPTC_SRGBA, RGBA8_UNORM, RGBA, S, _T__),
- /* Mesa does not yet support astc_decode_mode extensions, so non-sRGB
- * formats must be assumed to be wide.
+ /* If astc decode mode is set to RGBA8, the hardware format
+ * will be overriden to RGBA8_UNORM later on.
*/
FMT(ASTC_4x4, RGBA16F, RGBA, L, _T__),
FMT(ASTC_5x4, RGBA16F, RGBA, L, _T__),
diff --git a/src/panfrost/lib/pan_texture.c b/src/panfrost/lib/pan_texture.c
index a5a676ed45f..43f469cd9fb 100644
--- a/src/panfrost/lib/pan_texture.c
+++ b/src/panfrost/lib/pan_texture.c
@@ -357,7 +357,8 @@ translate_superblock_size(uint64_t modifier)
}
static void
-panfrost_emit_plane(int index, const struct pan_image_layout *layout,
+panfrost_emit_plane(const struct pan_image_view *iview, int index,
+ const struct pan_image_layout *layout,
enum pipe_format format, mali_ptr pointer, unsigned level,
int32_t row_stride, int32_t surface_stride,
mali_ptr plane2_ptr, void **payload)
@@ -409,12 +410,10 @@ panfrost_emit_plane(int index, const struct pan_image_layout *layout,
/* sRGB formats decode to RGBA8 sRGB, which is narrow.
*
- * Non-sRGB formats decode to RGBA16F which is wide.
- * With a future extension, we could decode non-sRGB
- * formats narrowly too, but this isn't wired up in Mesa
- * yet.
+ * Non-sRGB formats decode to RGBA16F which is wide except if decode
+ * precision is set to GL_RGBA8 for that texture.
*/
- cfg.astc.decode_wide = !srgb;
+ cfg.astc.decode_wide = !srgb && !iview->astc.narrow;
} else if (afbc) {
cfg.plane_type = MALI_PLANE_TYPE_AFBC;
cfg.afbc.superblock_size = translate_superblock_size(layout->modifier);
@@ -512,12 +511,12 @@ panfrost_emit_surface(const struct pan_image_view *iview, unsigned level,
/* 3-plane YUV requires equal stride for both chroma planes */
assert(row_strides[2] == 0 || row_strides[1] == row_strides[2]);
- panfrost_emit_plane(i, layouts[i], format, plane_ptrs[i], level,
+ panfrost_emit_plane(iview, i, layouts[i], format, plane_ptrs[i], level,
row_strides[i], surface_strides[i], plane_ptrs[2],
payload);
}
} else {
- panfrost_emit_plane(0, layouts[0], format, plane_ptrs[0], level,
+ panfrost_emit_plane(iview, 0, layouts[0], format, plane_ptrs[0], level,
row_strides[0], surface_strides[0], 0, payload);
}
return;
@@ -618,9 +617,15 @@ GENX(panfrost_new_texture)(const struct pan_image_view *iview, void *out,
const struct pan_image *base_image = pan_image_view_get_plane(iview, 0);
const struct pan_image_layout *layout = &base_image->layout;
enum pipe_format format = iview->format;
+ const struct util_format_description *desc = util_format_description(format);
uint32_t mali_format = GENX(panfrost_format_from_pipe_format)(format)->hw;
unsigned char swizzle[4];
+ if (desc->layout == UTIL_FORMAT_LAYOUT_ASTC && iview->astc.narrow &&
+ desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB) {
+ mali_format = MALI_PACK_FMT(RGBA8_UNORM, RGBA, L);
+ }
+
if (PAN_ARCH >= 7 && util_format_is_depth_or_stencil(format)) {
/* v7+ doesn't have an _RRRR component order, combine the
* user swizzle with a .XXXX swizzle to emulate that.
diff --git a/src/panfrost/lib/pan_texture.h b/src/panfrost/lib/pan_texture.h
index 3c5c04613f8..13235b06990 100644
--- a/src/panfrost/lib/pan_texture.h
+++ b/src/panfrost/lib/pan_texture.h
@@ -147,6 +147,10 @@ struct pan_image_view {
unsigned offset;
unsigned size;
} buf;
+
+ struct {
+ unsigned narrow;
+ } astc;
};
static inline const struct pan_image *