diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 15 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_mipmap_tree.c | 108 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_mipmap_tree.h | 25 |
3 files changed, 98 insertions, 50 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 66301a9b08c..298678a03c0 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -568,6 +568,21 @@ brw_init_surface_formats(struct brw_context *brw) * during glCompressedTexImage2D(). See intel_mipmap_tree::wraps_etc1. */ ctx->TextureFormatSupported[MESA_FORMAT_ETC1_RGB8] = true; + + /* On hardware that lacks support for ETC2, we map ETC2 to a suitable + * MESA_FORMAT during glCompressedTexImage2D(). + * See intel_mipmap_tree::wraps_etc2. + */ + ctx->TextureFormatSupported[MESA_FORMAT_ETC2_RGB8] = true; + ctx->TextureFormatSupported[MESA_FORMAT_ETC2_SRGB8] = true; + ctx->TextureFormatSupported[MESA_FORMAT_ETC2_RGBA8_EAC] = true; + ctx->TextureFormatSupported[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC] = true; + ctx->TextureFormatSupported[MESA_FORMAT_ETC2_R11_EAC] = true; + ctx->TextureFormatSupported[MESA_FORMAT_ETC2_RG11_EAC] = true; + ctx->TextureFormatSupported[MESA_FORMAT_ETC2_SIGNED_R11_EAC] = true; + ctx->TextureFormatSupported[MESA_FORMAT_ETC2_SIGNED_RG11_EAC] = true; + ctx->TextureFormatSupported[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] = true; + ctx->TextureFormatSupported[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] = true; } bool diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c index 04be7576653..609682769f2 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c @@ -199,14 +199,44 @@ intel_miptree_create(struct intel_context *intel, 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)) { @@ -257,7 +287,8 @@ intel_miptree_create(struct intel_context *intel, 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, @@ -1254,55 +1285,52 @@ intel_miptree_unmap_s8(struct intel_context *intel, } 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); @@ -1524,8 +1552,8 @@ intel_miptree_map_singlesample(struct intel_context *intel, 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 && @@ -1562,8 +1590,8 @@ intel_miptree_unmap_singlesample(struct intel_context *intel, 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) { diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h index 1a415fbce34..3a465da6e14 100644 --- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h @@ -197,11 +197,14 @@ struct intel_mipmap_tree * 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. @@ -351,16 +354,18 @@ struct intel_mipmap_tree 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: */ |