st/mesa: add a driconf option to transcode ETC2 to DXTC

for performance analysis

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9357>
This commit is contained in:
Marek Olšák 2021-02-24 13:11:07 -05:00 committed by Marge Bot
parent 8b6d22109f
commit 0bbae3139e
8 changed files with 86 additions and 27 deletions

View file

@ -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()

View file

@ -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 */

View file

@ -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];
};

View file

@ -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");
}
}
}

View file

@ -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);

View file

@ -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;

View file

@ -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");
}

View file

@ -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")