[Mesa-dev] [PATCH] i965: Transcode RGB ETC1/2 textures to DXT1 or FXT1.
Eric Anholt
eric at anholt.net
Fri Jan 11 20:54:37 PST 2013
The previous solution of transcoding to ARGB8888 gave exact results, but
below the expected performance. Given that the user has gone out of
their way to give us compressed data for performance reasons, try to
respect their wishes by doing the best compression we can handle. We
expect DXT1 compression to be better quality, but it may not always be
available, in which case FXT1 seems like a reasonable fallback.
This regresses OES_compressed_ETC1_RGB8_texture/miptree (which expects
exact results, which we no longer provide), but it improves GLBenchmark
2.1 offscreen performance by 3.2% +/- 2.1% (n=11/10, throttling
outliers removed).
---
src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 44 +++++++++++++++++++-----
1 file changed, 35 insertions(+), 9 deletions(-)
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 7542219..73411c6 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -295,6 +295,7 @@ intel_miptree_create(struct intel_context *intel,
GLuint num_samples,
bool force_y_tiling)
{
+ struct gl_context *ctx = &intel->ctx;
struct intel_mipmap_tree *mt;
uint32_t tiling = I915_TILING_NONE;
GLenum base_format;
@@ -304,10 +305,11 @@ intel_miptree_create(struct intel_context *intel,
switch (format) {
case MESA_FORMAT_ETC1_RGB8:
- format = MESA_FORMAT_RGBX8888_REV;
- break;
case MESA_FORMAT_ETC2_RGB8:
- format = MESA_FORMAT_RGBX8888_REV;
+ if (ctx->Mesa_DXTn)
+ format = MESA_FORMAT_RGB_DXT1;
+ else
+ format = MESA_FORMAT_RGB_FXT1;
break;
case MESA_FORMAT_ETC2_SRGB8:
case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
@@ -1299,10 +1301,6 @@ intel_miptree_map_etc(struct intel_context *intel,
*/
assert(mt->wraps_etc);
- if (mt->etc_format == MESA_FORMAT_ETC1_RGB8) {
- assert(mt->format == MESA_FORMAT_RGBX8888_REV);
- }
-
assert(map->mode & GL_MAP_WRITE_BIT);
assert(map->mode & GL_MAP_INVALIDATE_RANGE_BIT);
@@ -1319,6 +1317,7 @@ intel_miptree_unmap_etc(struct intel_context *intel,
unsigned int level,
unsigned int slice)
{
+ struct gl_context *ctx = &intel->ctx;
uint32_t image_x;
uint32_t image_y;
intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
@@ -1330,11 +1329,38 @@ intel_miptree_unmap_etc(struct intel_context *intel,
+ image_y * mt->region->pitch * mt->region->cpp
+ image_x * mt->region->cpp;
- if (mt->etc_format == MESA_FORMAT_ETC1_RGB8)
+ if (mt->format == MESA_FORMAT_RGB_DXT1 ||
+ mt->format == MESA_FORMAT_RGB_FXT1) {
+ unsigned int bw, bh;
+ _mesa_get_format_block_size(mt->etc_format, &bw, &bh);
+
+ int rgba_temp_w = ALIGN(map->w, bw);
+ int rgba_temp_h = ALIGN(map->h, bh);
+ void *rgba_temp = malloc(_mesa_format_image_size(MESA_FORMAT_RGBA8888,
+ rgba_temp_w, rgba_temp_h, 1));
+ int rgba_stride = _mesa_format_row_stride(MESA_FORMAT_RGBA8888,
+ rgba_temp_w);
+ if (mt->etc_format == MESA_FORMAT_ETC1_RGB8) {
+ _mesa_etc1_unpack_rgba8888(rgba_temp, rgba_stride,
+ map->ptr, map->stride,
+ map->w, map->h);
+ } else {
+ _mesa_unpack_etc2_format(rgba_temp, rgba_stride,
+ map->ptr, map->stride,
+ map->w, map->h, mt->etc_format);
+ }
+ _mesa_texstore(ctx, 2, GL_RGB,
+ mt->format,
+ mt->region->pitch * mt->region->cpp, &dst,
+ map->w, map->h, 1,
+ GL_RGBA, GL_UNSIGNED_BYTE, rgba_temp,
+ &ctx->DefaultPacking);
+ free(rgba_temp);
+ } else if (mt->etc_format == MESA_FORMAT_ETC1_RGB8) {
_mesa_etc1_unpack_rgba8888(dst, mt->region->pitch * mt->region->cpp,
map->ptr, map->stride,
map->w, map->h);
- else
+ } else
_mesa_unpack_etc2_format(dst, mt->region->pitch * mt->region->cpp,
map->ptr, map->stride,
map->w, map->h, mt->etc_format);
--
1.7.10.4
More information about the mesa-dev
mailing list