From 0127d26e6c25974a84102fba2f556e260ccbcaeb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sat, 2 Aug 2014 21:38:25 +0200 Subject: [PATCH] st/mesa: convert the ETC1 format to an uncompressed one if unsupported I don't know of any hardware which supports it. With this, GL_OES_compressed_ETC1_RGB8_texture is supported if RGBA8 is supported. Reviewed-by: Glenn Kennard --- docs/relnotes/10.3.html | 1 + src/mesa/state_tracker/st_cb_texture.c | 31 ++++++++++++++++++-------- src/mesa/state_tracker/st_context.c | 3 +++ src/mesa/state_tracker/st_context.h | 1 + src/mesa/state_tracker/st_extensions.c | 4 +++- src/mesa/state_tracker/st_format.c | 13 +++++++++-- 6 files changed, 41 insertions(+), 12 deletions(-) diff --git a/docs/relnotes/10.3.html b/docs/relnotes/10.3.html index c0828da713d..a1f2777129c 100644 --- a/docs/relnotes/10.3.html +++ b/docs/relnotes/10.3.html @@ -60,6 +60,7 @@ Note: some of the new features are only available with certain drivers.
  • GL_ARB_fragment_layer_viewport on nv50, nvc0, llvmpipe, r600
  • GL_AMD_vertex_shader_viewport_index on i965/gen7+, r600
  • GL_ARB_clear_texture on i965
  • +
  • GL_OES_compressed_ETC1_RGB8_texture on nv30, nv50, nvc0, r300, r600, radeonsi, softpipe, llvmpipe
  • A new software rasterizer driver (kms_swrast_dri.so) that works with DRM drivers that don't have a full-fledged GEM (such as qxl or simpledrm)
  • diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 1b065e4f04b..969a05f5297 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -208,7 +208,8 @@ st_MapTextureImage(struct gl_context *ctx, map = st_texture_image_map(st, stImage, pipeMode, x, y, slice, w, h, 1, &transfer); if (map) { - if (_mesa_is_format_etc2(texImage->TexFormat)) { + if (_mesa_is_format_etc2(texImage->TexFormat) || + (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8 && !st->has_etc1)) { /* ETC isn't supported by gallium and it's represented * by uncompressed formats. Only write transfers with precompressed * data are supported by ES3, which makes this really simple. @@ -250,7 +251,8 @@ st_UnmapTextureImage(struct gl_context *ctx, struct st_context *st = st_context(ctx); struct st_texture_image *stImage = st_texture_image(texImage); - if (_mesa_is_format_etc2(texImage->TexFormat)) { + if (_mesa_is_format_etc2(texImage->TexFormat) || + (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8 && !st->has_etc1)) { /* Decompress the ETC texture to the mapped one. */ unsigned z = slice + stImage->base.Face; struct st_texture_image_transfer *itransfer = &stImage->transfer[z]; @@ -258,10 +260,18 @@ st_UnmapTextureImage(struct gl_context *ctx, assert(z == transfer->box.z); - _mesa_unpack_etc2_format(itransfer->map, transfer->stride, - itransfer->temp_data, itransfer->temp_stride, - transfer->box.width, transfer->box.height, - texImage->TexFormat); + 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 { + _mesa_unpack_etc2_format(itransfer->map, transfer->stride, + itransfer->temp_data, itransfer->temp_stride, + transfer->box.width, transfer->box.height, + texImage->TexFormat); + } free(itransfer->temp_data); itransfer->temp_data = NULL; @@ -657,7 +667,8 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims, unsigned bind; GLubyte *map; - assert(!_mesa_is_format_etc2(texImage->TexFormat)); + assert(!_mesa_is_format_etc2(texImage->TexFormat) && + texImage->TexFormat != MESA_FORMAT_ETC1_RGB8); if (!st->prefer_blit_based_texture_transfer) { goto fallback; @@ -918,7 +929,8 @@ st_GetTexImage(struct gl_context * ctx, ubyte *map = NULL; boolean done = FALSE; - assert(!_mesa_is_format_etc2(texImage->TexFormat)); + assert(!_mesa_is_format_etc2(texImage->TexFormat) && + texImage->TexFormat != MESA_FORMAT_ETC1_RGB8); if (!st->prefer_blit_based_texture_transfer && !_mesa_is_format_compressed(texImage->TexFormat)) { @@ -1356,7 +1368,8 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims, unsigned bind; GLint srcY0, srcY1; - assert(!_mesa_is_format_etc2(texImage->TexFormat)); + assert(!_mesa_is_format_etc2(texImage->TexFormat) && + texImage->TexFormat != MESA_FORMAT_ETC1_RGB8); if (!strb || !strb->surface || !stImage->pt) { debug_printf("%s: null strb or stImage\n", __FUNCTION__); diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index c805a094b98..ccd19f3e361 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -189,6 +189,9 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe, st->has_stencil_export = screen->get_param(screen, PIPE_CAP_SHADER_STENCIL_EXPORT); st->has_shader_model3 = screen->get_param(screen, PIPE_CAP_SM3); + st->has_etc1 = screen->is_format_supported(screen, PIPE_FORMAT_ETC1_RGB8, + PIPE_TEXTURE_2D, 0, + PIPE_BIND_SAMPLER_VIEW); st->prefer_blit_based_texture_transfer = screen->get_param(screen, PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER); diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 361a24b1d71..6d572bd4907 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -86,6 +86,7 @@ struct st_context boolean has_stencil_export; /**< can do shader stencil export? */ boolean has_time_elapsed; boolean has_shader_model3; + boolean has_etc1; boolean prefer_blit_based_texture_transfer; boolean needs_texcoord_semantic; diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 3974adb49a4..60aa8ccec0b 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -513,7 +513,9 @@ void st_init_extensions(struct st_context *st) GL_TRUE }, /* at least one format must be supported */ { { o(OES_compressed_ETC1_RGB8_texture) }, - { PIPE_FORMAT_ETC1_RGB8 } }, + { PIPE_FORMAT_ETC1_RGB8, + PIPE_FORMAT_R8G8B8A8_UNORM }, + GL_TRUE }, /* at least one format must be supported */ { { o(ARB_stencil_texturing) }, { PIPE_FORMAT_X24S8_UINT, diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index 3d822a5a4e4..ae71dd786cf 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -323,8 +323,10 @@ st_mesa_format_to_pipe_format(struct st_context *st, mesa_format mesaFormat) case MESA_FORMAT_LA_LATC2_SNORM: return PIPE_FORMAT_LATC2_SNORM; + /* The destination RGBA format mustn't be changed, because it's also + * a destination format of the unpack/decompression function. */ case MESA_FORMAT_ETC1_RGB8: - return PIPE_FORMAT_ETC1_RGB8; + return st->has_etc1 ? PIPE_FORMAT_ETC1_RGB8 : PIPE_FORMAT_R8G8B8A8_UNORM; /* signed normalized formats */ case MESA_FORMAT_R_SNORM8: @@ -801,9 +803,11 @@ test_format_conversion(struct st_context *st) /* test all Mesa formats */ for (i = 1; i < MESA_FORMAT_COUNT; i++) { - /* ETC2 formats are translated differently, skip them. */ + /* ETC formats are translated differently, skip them. */ if (_mesa_is_format_etc2(i)) continue; + if (i == MESA_FORMAT_ETC1_RGB8 && !st->has_etc1) + continue; enum pipe_format pf = st_mesa_format_to_pipe_format(st, i); if (pf != PIPE_FORMAT_NONE) { @@ -815,6 +819,11 @@ test_format_conversion(struct st_context *st) /* Test all Gallium formats */ for (i = 1; i < PIPE_FORMAT_COUNT; i++) { mesa_format mf = st_pipe_format_to_mesa_format(i); + + /* ETC formats are translated differently, skip them. */ + if (i == PIPE_FORMAT_ETC1_RGB8 && !st->has_etc1) + continue; + if (mf != MESA_FORMAT_NONE) { enum pipe_format pf = st_mesa_format_to_pipe_format(st, mf); assert(pf == i); -- 2.30.2