From: Marek Olšák Date: Wed, 24 Feb 2021 18:11:07 +0000 (-0500) Subject: st/mesa: add a driconf option to transcode ETC2 to DXTC X-Git-Tag: upstream/21.2.3~6295 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0bbae3139ef4cdbfbcf5818ec7ee0f3804b02e90;p=platform%2Fupstream%2Fmesa.git st/mesa: add a driconf option to transcode ETC2 to DXTC for performance analysis Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- diff --git a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h index 4fd0804..9c5cdfb 100644 --- a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h +++ b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h @@ -33,6 +33,7 @@ DRI_CONF_SECTION_DEBUG DRI_CONF_ALLOW_INCORRECT_PRIMITIVE_ID(false) DRI_CONF_FORCE_COMPAT_PROFILE(false) DRI_CONF_FORCE_GL_NAMES_REUSE(false) + DRI_CONF_TRANSCODE_ETC(false) DRI_CONF_FORCE_GL_VENDOR() DRI_CONF_OVERRIDE_VRAM_SIZE() DRI_CONF_GLX_EXTENSION_OVERRIDE() diff --git a/src/gallium/frontends/dri/dri_screen.c b/src/gallium/frontends/dri/dri_screen.c index d393811..3f614f8 100644 --- a/src/gallium/frontends/dri/dri_screen.c +++ b/src/gallium/frontends/dri/dri_screen.c @@ -103,6 +103,8 @@ dri_fill_st_options(struct dri_screen *screen) driQueryOptionb(optionCache, "ignore_map_unsynchronized"); options->force_gl_names_reuse = driQueryOptionb(optionCache, "force_gl_names_reuse"); + options->transcode_etc = + driQueryOptionb(optionCache, "transcode_etc"); char *vendor_str = driQueryOptionstr(optionCache, "force_gl_vendor"); /* not an empty string */ diff --git a/src/gallium/include/frontend/api.h b/src/gallium/include/frontend/api.h index 3d051234..e271033 100644 --- a/src/gallium/include/frontend/api.h +++ b/src/gallium/include/frontend/api.h @@ -245,6 +245,7 @@ struct st_config_options bool ignore_map_unsynchronized; bool force_integer_tex_nearest; bool force_gl_names_reuse; + bool transcode_etc; char *force_gl_vendor; unsigned char config_options_sha1[20]; }; diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 4639440..6b26919 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -382,28 +382,72 @@ st_UnmapTextureImage(struct gl_context *ctx, assert(z == transfer->box.z); if (transfer->usage & PIPE_MAP_WRITE) { - if (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8) { - _mesa_etc1_unpack_rgba8888(itransfer->map, transfer->stride, - itransfer->temp_data, - itransfer->temp_stride, + if (util_format_is_compressed(stImage->pt->format)) { + /* Transcode into a different compressed format. */ + unsigned size = + _mesa_format_image_size(PIPE_FORMAT_R8G8B8A8_UNORM, transfer->box.width, - transfer->box.height); - } else if (_mesa_is_format_etc2(texImage->TexFormat)) { - bool bgra = stImage->pt->format == PIPE_FORMAT_B8G8R8A8_SRGB; - _mesa_unpack_etc2_format(itransfer->map, transfer->stride, - itransfer->temp_data, - itransfer->temp_stride, - transfer->box.width, transfer->box.height, - texImage->TexFormat, - bgra); - } else if (_mesa_is_format_astc_2d(texImage->TexFormat)) { - _mesa_unpack_astc_2d_ldr(itransfer->map, transfer->stride, - itransfer->temp_data, - itransfer->temp_stride, - transfer->box.width, transfer->box.height, - texImage->TexFormat); + transfer->box.height, 1); + void *tmp = malloc(size); + + /* Decompress to tmp. */ + if (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8) { + _mesa_etc1_unpack_rgba8888(tmp, transfer->box.width * 4, + itransfer->temp_data, + itransfer->temp_stride, + transfer->box.width, + transfer->box.height); + } else if (_mesa_is_format_etc2(texImage->TexFormat)) { + bool bgra = stImage->pt->format == PIPE_FORMAT_B8G8R8A8_SRGB; + + _mesa_unpack_etc2_format(tmp, transfer->box.width * 4, + itransfer->temp_data, + itransfer->temp_stride, + transfer->box.width, + transfer->box.height, + texImage->TexFormat, + bgra); + } else { + /* TODO: We could transcode ASTC too. */ + unreachable("unexpected format for a compressed format fallback"); + } + + /* Compress it to the target format. */ + struct gl_pixelstore_attrib pack = {0}; + pack.Alignment = 4; + + _mesa_texstore(ctx, 2, GL_RGBA, stImage->pt->format, + transfer->stride, &itransfer->map, + transfer->box.width, + transfer->box.height, 1, GL_RGBA, + GL_UNSIGNED_BYTE, tmp, &pack); + free(tmp); } else { - unreachable("unexpected format for a compressed format fallback"); + /* Decompress into an uncompressed format. */ + if (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8) { + _mesa_etc1_unpack_rgba8888(itransfer->map, transfer->stride, + itransfer->temp_data, + itransfer->temp_stride, + transfer->box.width, + transfer->box.height); + } else if (_mesa_is_format_etc2(texImage->TexFormat)) { + bool bgra = stImage->pt->format == PIPE_FORMAT_B8G8R8A8_SRGB; + + _mesa_unpack_etc2_format(itransfer->map, transfer->stride, + itransfer->temp_data, + itransfer->temp_stride, + transfer->box.width, transfer->box.height, + texImage->TexFormat, + bgra); + } else if (_mesa_is_format_astc_2d(texImage->TexFormat)) { + _mesa_unpack_astc_2d_ldr(itransfer->map, transfer->stride, + itransfer->temp_data, + itransfer->temp_stride, + transfer->box.width, transfer->box.height, + texImage->TexFormat); + } else { + unreachable("unexpected format for a compressed format fallback"); + } } } diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 3acbc75..07dad53 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -677,6 +677,10 @@ st_create_context_priv(struct gl_context *ctx, struct pipe_context *pipe, st->has_etc2 = screen->is_format_supported(screen, PIPE_FORMAT_ETC2_RGB8, PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW); + st->transcode_etc = options->transcode_etc && + screen->is_format_supported(screen, PIPE_FORMAT_DXT1_SRGBA, + PIPE_TEXTURE_2D, 0, 0, + PIPE_BIND_SAMPLER_VIEW); st->has_astc_2d_ldr = screen->is_format_supported(screen, PIPE_FORMAT_ASTC_4x4_SRGB, PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index fe0a085..867a882 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -142,6 +142,7 @@ struct st_context boolean has_time_elapsed; boolean has_etc1; boolean has_etc2; + boolean transcode_etc; boolean has_astc_2d_ldr; boolean has_astc_5x5_ldr; boolean prefer_blit_based_texture_transfer; diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index cc56210..6f71bfe 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -68,7 +68,7 @@ st_mesa_format_to_pipe_format(const struct st_context *st, * a destination format of the unpack/decompression function. */ if (mesaFormat == MESA_FORMAT_ETC1_RGB8 && !st->has_etc1) - return PIPE_FORMAT_R8G8B8A8_UNORM; + return st->transcode_etc ? PIPE_FORMAT_DXT1_RGB : PIPE_FORMAT_R8G8B8A8_UNORM; /* ETC2 formats are emulated as uncompressed ones. * The destination formats mustn't be changed, because they are also @@ -82,13 +82,15 @@ st_mesa_format_to_pipe_format(const struct st_context *st, switch (mesaFormat) { case MESA_FORMAT_ETC2_RGB8: - return PIPE_FORMAT_R8G8B8A8_UNORM; + return st->transcode_etc ? PIPE_FORMAT_DXT1_RGB : PIPE_FORMAT_R8G8B8A8_UNORM; case MESA_FORMAT_ETC2_SRGB8: - return has_bgra_srgb ? PIPE_FORMAT_B8G8R8A8_SRGB : PIPE_FORMAT_R8G8B8A8_SRGB; + return st->transcode_etc ? PIPE_FORMAT_DXT1_SRGB : + has_bgra_srgb ? PIPE_FORMAT_B8G8R8A8_SRGB : PIPE_FORMAT_R8G8B8A8_SRGB; case MESA_FORMAT_ETC2_RGBA8_EAC: - return PIPE_FORMAT_R8G8B8A8_UNORM; + return st->transcode_etc ? PIPE_FORMAT_DXT5_RGBA : PIPE_FORMAT_R8G8B8A8_UNORM; case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: - return has_bgra_srgb ? PIPE_FORMAT_B8G8R8A8_SRGB : PIPE_FORMAT_R8G8B8A8_SRGB; + return st->transcode_etc ? PIPE_FORMAT_DXT5_SRGBA : + has_bgra_srgb ? PIPE_FORMAT_B8G8R8A8_SRGB : PIPE_FORMAT_R8G8B8A8_SRGB; case MESA_FORMAT_ETC2_R11_EAC: return PIPE_FORMAT_R16_UNORM; case MESA_FORMAT_ETC2_RG11_EAC: @@ -98,9 +100,10 @@ st_mesa_format_to_pipe_format(const struct st_context *st, case MESA_FORMAT_ETC2_SIGNED_RG11_EAC: return PIPE_FORMAT_R16G16_SNORM; case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: - return PIPE_FORMAT_R8G8B8A8_UNORM; + return st->transcode_etc ? PIPE_FORMAT_DXT1_RGBA : PIPE_FORMAT_R8G8B8A8_UNORM; case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: - return has_bgra_srgb ? PIPE_FORMAT_B8G8R8A8_SRGB : PIPE_FORMAT_R8G8B8A8_SRGB; + return st->transcode_etc ? PIPE_FORMAT_DXT1_SRGBA : + has_bgra_srgb ? PIPE_FORMAT_B8G8R8A8_SRGB : PIPE_FORMAT_R8G8B8A8_SRGB; default: unreachable("Unknown ETC2 format"); } diff --git a/src/util/driconf.h b/src/util/driconf.h index 9c0c353..48be630 100644 --- a/src/util/driconf.h +++ b/src/util/driconf.h @@ -221,6 +221,9 @@ #define DRI_CONF_FORCE_GL_NAMES_REUSE(def) \ DRI_CONF_OPT_B(force_gl_names_reuse, def, "Force GL names reuse") +#define DRI_CONF_TRANSCODE_ETC(def) \ + DRI_CONF_OPT_B(transcode_etc, def, "Transcode ETC formats to DXTC if unsupported") + #define DRI_CONF_GLX_EXTENSION_OVERRIDE(def) \ DRI_CONF_OPT_S(glx_extension_override, def, \ "Allow enabling/disabling a list of GLX extensions")