struct intel_mipmap_tree *mt;
uint32_t tiling = I915_TILING_NONE;
GLenum base_format;
- bool wraps_etc1 = false;
+ gl_format tex_format = format;
+ gl_format etc_format = MESA_FORMAT_NONE;
GLuint total_width, total_height;
- if (format == MESA_FORMAT_ETC1_RGB8) {
+ switch (format) {
+ case MESA_FORMAT_ETC1_RGB8:
format = MESA_FORMAT_RGBX8888_REV;
- wraps_etc1 = true;
+ break;
+ case MESA_FORMAT_ETC2_RGB8:
+ format = MESA_FORMAT_RGBX8888_REV;
+ break;
+ case MESA_FORMAT_ETC2_SRGB8:
+ case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
+ case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
+ format = MESA_FORMAT_SARGB8;
+ break;
+ case MESA_FORMAT_ETC2_RGBA8_EAC:
+ case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
+ format = MESA_FORMAT_RGBA8888_REV;
+ break;
+ case MESA_FORMAT_ETC2_R11_EAC:
+ format = MESA_FORMAT_R16;
+ break;
+ case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
+ format = MESA_FORMAT_SIGNED_R16;
+ break;
+ case MESA_FORMAT_ETC2_RG11_EAC:
+ format = MESA_FORMAT_RG1616;
+ break;
+ case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
+ format = MESA_FORMAT_SIGNED_GR1616;
+ break;
+ default:
+ /* Non ETC1 / ETC2 format */
+ break;
}
+ etc_format = (format != tex_format) ? tex_format : MESA_FORMAT_NONE;
base_format = _mesa_get_format_base_format(format);
if (intel->use_texture_tiling && !_mesa_is_format_compressed(format)) {
total_height = ALIGN(total_height, 64);
}
- mt->wraps_etc1 = wraps_etc1;
+ mt->wraps_etc = (etc_format != MESA_FORMAT_NONE) ? true : false;
+ mt->etc_format = etc_format;
mt->region = intel_region_alloc(intel->intelScreen,
tiling,
mt->cpp,
}
static void
-intel_miptree_map_etc1(struct intel_context *intel,
- struct intel_mipmap_tree *mt,
- struct intel_miptree_map *map,
- unsigned int level,
- unsigned int slice)
+intel_miptree_map_etc(struct intel_context *intel,
+ struct intel_mipmap_tree *mt,
+ struct intel_miptree_map *map,
+ unsigned int level,
+ unsigned int slice)
{
- /* For justification of these invariants,
- * see intel_mipmap_tree:wraps_etc1.
+ /* For justification see intel_mipmap_tree:wraps_etc.
*/
- assert(mt->wraps_etc1);
- assert(mt->format == MESA_FORMAT_RGBX8888_REV);
+ assert(mt->wraps_etc);
+
+ if (mt->etc_format == MESA_FORMAT_ETC1_RGB8) {
+ assert(mt->format == MESA_FORMAT_RGBX8888_REV);
+ }
- /* From the GL_OES_compressed_ETC1_RGB8_texture spec:
- * INVALID_OPERATION is generated by CompressedTexSubImage2D,
- * TexSubImage2D, or CopyTexSubImage2D if the texture image <level>
- * bound to <target> has internal format ETC1_RGB8_OES.
- *
- * This implies that intel_miptree_map_etc1() can only be called from
- * glCompressedTexImage2D, and hence the assertions below hold.
- */
assert(map->mode & GL_MAP_WRITE_BIT);
assert(map->mode & GL_MAP_INVALIDATE_RANGE_BIT);
- assert(map->x == 0);
- assert(map->y == 0);
- map->stride = _mesa_format_row_stride(MESA_FORMAT_ETC1_RGB8, map->w);
- map->buffer = malloc(_mesa_format_image_size(MESA_FORMAT_ETC1_RGB8,
+ map->stride = _mesa_format_row_stride(mt->etc_format, map->w);
+ map->buffer = malloc(_mesa_format_image_size(mt->etc_format,
map->w, map->h, 1));
map->ptr = map->buffer;
}
static void
-intel_miptree_unmap_etc1(struct intel_context *intel,
- struct intel_mipmap_tree *mt,
- struct intel_miptree_map *map,
- unsigned int level,
- unsigned int slice)
+intel_miptree_unmap_etc(struct intel_context *intel,
+ struct intel_mipmap_tree *mt,
+ struct intel_miptree_map *map,
+ unsigned int level,
+ unsigned int slice)
{
uint32_t image_x;
uint32_t image_y;
intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
- uint8_t *xbgr = intel_region_map(intel, mt->region, map->mode)
- + image_y * mt->region->pitch * mt->region->cpp
- + image_x * mt->region->cpp;
+ uint8_t *dst = intel_region_map(intel, mt->region, map->mode)
+ + image_y * mt->region->pitch * mt->region->cpp
+ + image_x * mt->region->cpp;
- _mesa_etc1_unpack_rgba8888(xbgr, mt->region->pitch * mt->region->cpp,
- map->ptr, map->stride,
- map->w, map->h);
+ 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
+ _mesa_unpack_etc2_format(dst, mt->region->pitch * mt->region->cpp,
+ map->ptr, map->stride,
+ map->w, map->h, mt->etc_format);
intel_region_unmap(intel, mt->region);
free(map->buffer);
if (mt->format == MESA_FORMAT_S8) {
intel_miptree_map_s8(intel, mt, map, level, slice);
- } else if (mt->wraps_etc1) {
- intel_miptree_map_etc1(intel, mt, map, level, slice);
+ } else if (mt->wraps_etc) {
+ intel_miptree_map_etc(intel, mt, map, level, slice);
} else if (mt->stencil_mt) {
intel_miptree_map_depthstencil(intel, mt, map, level, slice);
} else if (intel->has_llc &&
if (mt->format == MESA_FORMAT_S8) {
intel_miptree_unmap_s8(intel, mt, map, level, slice);
- } else if (mt->wraps_etc1) {
- intel_miptree_unmap_etc1(intel, mt, map, level, slice);
+ } else if (mt->wraps_etc) {
+ intel_miptree_unmap_etc(intel, mt, map, level, slice);
} else if (mt->stencil_mt) {
intel_miptree_unmap_depthstencil(intel, mt, map, level, slice);
} else if (map->bo) {
* MESA_FORMAT_Z32_FLOAT, otherwise for MESA_FORMAT_S8_Z24 objects it will be
* MESA_FORMAT_X8_Z24.
*
- * For ETC1 textures, this is MESA_FORMAT_RGBX8888_REV if the hardware
- * lacks support for ETC1. See @ref wraps_etc1.
+ * For ETC1/ETC2 textures, this is one of the uncompressed mesa texture
+ * formats if the hardware lacks support for ETC1/ETC2. See @ref wraps_etc.
*/
gl_format format;
+ /** This variable stores the value of ETC compressed texture format */
+ gl_format etc_format;
+
/**
* The X offset of each image in the miptree must be aligned to this. See
* the "Alignment Unit Size" section of the BSpec.
struct intel_mipmap_tree *mcs_mt;
/**
- * \brief The miptree contains RGBX data that was originally ETC1 data.
+ * \brief The miptree contains uncompressed data that was originally
+ * ETC1/ETC2 data.
*
- * On hardware that lacks support for ETC1 textures, we do the
- * following on calls to glCompressedTexImage2D(GL_ETC1_RGB8_OES):
- * 1. Create a miptree whose format is MESA_FORMAT_RGBX8888_REV with
- * the wraps_etc1 flag set.
- * 2. Translate the ETC1 data into RGBX.
- * 3. Store the RGBX data into the miptree and discard the ETC1 data.
+ * On hardware that lacks support for ETC1/ETC2 textures, we do the following
+ * on calls to glCompressedTexImage2D() with an ETC1/ETC2 texture format:
+ * 1. Create a miptree whose format is a suitable uncompressed mesa format
+ * with the wraps_etc flag set.
+ * 2. Translate the ETC1/ETC2 data into uncompressed mesa format.
+ * 3. Store the uncompressed data into the miptree and discard the ETC1/ETC2
+ * data.
*/
- bool wraps_etc1;
+ bool wraps_etc;
/* These are also refcounted:
*/