summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChad Versace <chad.versace@linux.intel.com>2012-06-18 18:25:25 -0700
committerChad Versace <chad.versace@linux.intel.com>2012-07-16 14:11:12 -0700
commita5a34b153d494ad4374e7b2c8ea13b1073a887e2 (patch)
treed2fd53dd8e1a34c04fd5493c3d4bdd67c8b38117
parent8ec721264c7ae0f73a520362963b2691bf098b9b (diff)
intel: Enable GL_OES_compressed_ETC1_RGB8_texture
Enable it for all hardware. No current hardware supports ETC1, so this patch implements it by translating the ETC1 data to RGBX data during the call to glCompressedTexImage2D(). For details, see the doxygen for intel_mipmap_tree::wraps_etc1. Passes the Piglit test spec/OES_compressed_ETC1_RGB8_texture/miptree and the ETC1 test in the GLES2 conformance suite. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c5
-rwxr-xr-xsrc/mesa/drivers/dri/intel/intel_extensions.c1
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.c70
-rw-r--r--src/mesa/drivers/dri/intel/intel_mipmap_tree.h3
4 files changed, 78 insertions, 1 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 ddf38e3dd35..82e44f9b83a 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -548,12 +548,17 @@ brw_init_surface_formats(struct brw_context *brw)
*/
ctx->TextureFormatSupported[MESA_FORMAT_S8_Z24] = true;
ctx->TextureFormatSupported[MESA_FORMAT_X8_Z24] = true;
ctx->TextureFormatSupported[MESA_FORMAT_Z32_FLOAT] = true;
ctx->TextureFormatSupported[MESA_FORMAT_Z32_FLOAT_X24S8] = true;
ctx->TextureFormatSupported[MESA_FORMAT_Z16] = true;
+
+ /* On hardware that lacks support for ETC1, we map ETC1 to RGBX
+ * during glCompressedTexImage2D(). See intel_mipmap_tree::wraps_etc1.
+ */
+ ctx->TextureFormatSupported[MESA_FORMAT_ETC1_RGB8] = true;
}
bool
brw_render_target_supported(struct intel_context *intel,
struct gl_renderbuffer *rb)
{
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c
index 953b98389c3..844125dc8a5 100755
--- a/src/mesa/drivers/dri/intel/intel_extensions.c
+++ b/src/mesa/drivers/dri/intel/intel_extensions.c
@@ -88,12 +88,13 @@ intelInitExtensions(struct gl_context *ctx)
ctx->Extensions.NV_vertex_program1_1 = true;
ctx->Extensions.TDFX_texture_compression_FXT1 = true;
#if FEATURE_OES_EGL_image
ctx->Extensions.OES_EGL_image = true;
#endif
ctx->Extensions.OES_draw_texture = true;
+ ctx->Extensions.OES_compressed_ETC1_RGB8_texture = true;
if (intel->gen >= 6)
ctx->Const.GLSLVersion = 130;
else
ctx->Const.GLSLVersion = 120;
_mesa_override_glsl_version(ctx);
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
index 4e892b27fd1..d6572cd90f1 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.c
@@ -35,12 +35,13 @@
#include "intel_tex.h"
#include "intel_blit.h"
#include "main/enums.h"
#include "main/formats.h"
#include "main/image.h"
+#include "main/texcompress_etc.h"
#include "main/teximage.h"
#define FILE_DEBUG_FLAG DEBUG_MIPTREE
static GLenum
target_to_target(GLenum target)
@@ -187,13 +188,21 @@ intel_miptree_create(struct intel_context *intel,
bool expect_accelerated_upload,
GLuint num_samples,
enum intel_msaa_layout msaa_layout)
{
struct intel_mipmap_tree *mt;
uint32_t tiling = I915_TILING_NONE;
- GLenum base_format = _mesa_get_format_base_format(format);
+ GLenum base_format;
+ bool wraps_etc1 = false;
+
+ if (format == MESA_FORMAT_ETC1_RGB8) {
+ format = MESA_FORMAT_RGBX8888_REV;
+ wraps_etc1 = true;
+ }
+
+ base_format = _mesa_get_format_base_format(format);
if (intel->use_texture_tiling && !_mesa_is_format_compressed(format)) {
if (intel->gen >= 4 &&
(base_format == GL_DEPTH_COMPONENT ||
base_format == GL_DEPTH_STENCIL_EXT))
tiling = I915_TILING_Y;
@@ -234,12 +243,13 @@ intel_miptree_create(struct intel_context *intel,
*/
if (!mt || !mt->total_width || !mt->total_height) {
intel_miptree_release(&mt);
return NULL;
}
+ mt->wraps_etc1 = wraps_etc1;
mt->region = intel_region_alloc(intel->intelScreen,
tiling,
mt->cpp,
mt->total_width,
mt->total_height,
expect_accelerated_upload);
@@ -1046,12 +1056,66 @@ intel_miptree_unmap_s8(struct intel_context *intel,
intel_region_unmap(intel, mt->region);
}
free(map->buffer);
}
+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)
+{
+ /* For justification of these invariants,
+ * see intel_mipmap_tree:wraps_etc1.
+ */
+ assert(mt->wraps_etc1);
+ 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);
+
+ /* Each ETC1 block contains 4x4 pixels in 8 bytes. */
+ map->stride = 2 * map->w;
+ map->buffer = map->ptr = malloc(map->stride * map->h);
+}
+
+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)
+{
+ uint32_t image_x;
+ uint32_t image_y;
+ intel_miptree_get_image_offset(mt, level, 0, 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;
+
+ _mesa_etc1_unpack_rgba8888(xbgr, mt->region->pitch * mt->region->cpp,
+ map->ptr, map->stride,
+ map->w, map->h);
+
+ intel_region_unmap(intel, mt->region);
+ free(map->buffer);
+}
+
/**
* Mapping function for packed depth/stencil miptrees backed by real separate
* miptrees for depth and stencil.
*
* On gen7, and to support HiZ pre-gen7, we have to have the stencil buffer
* separate from the depth buffer. Yet at the GL API level, we have to expose
@@ -1222,12 +1286,14 @@ intel_miptree_map(struct intel_context *intel,
if (map->mode & GL_MAP_WRITE_BIT) {
intel_miptree_slice_set_needs_hiz_resolve(mt, level, slice);
}
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->stencil_mt) {
intel_miptree_map_depthstencil(intel, mt, map, level, slice);
} else if (intel->has_llc &&
!(mode & GL_MAP_WRITE_BIT) &&
!mt->compressed &&
mt->region->tiling == I915_TILING_X) {
@@ -1258,12 +1324,14 @@ intel_miptree_unmap(struct intel_context *intel,
DBG("%s: mt %p (%s) level %d slice %d\n", __FUNCTION__,
mt, _mesa_get_format_name(mt->format), level, slice);
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->stencil_mt) {
intel_miptree_unmap_depthstencil(intel, mt, map, level, slice);
} else if (map->bo) {
intel_miptree_unmap_blit(intel, mt, map, level, slice);
} else {
intel_miptree_unmap_gtt(intel, mt, map, level, slice);
diff --git a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
index 74fcc796cf5..2fb5775c02f 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
@@ -187,12 +187,15 @@ struct intel_mipmap_tree
* However, for textures and renderbuffers with packed depth/stencil formats
* on hardware where we want or need to use separate stencil, there will be
* two miptrees for storing the data. If the depthstencil texture or rb is
* MESA_FORMAT_Z32_FLOAT_X24S8, then mt->format will be
* 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.
*/
gl_format format;
/**
* The X offset of each image in the miptree must be aligned to this. See
* the "Alignment Unit Size" section of the BSpec.