summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/intel
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/intel')
-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
3 files changed, 73 insertions, 1 deletions
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
@@ -91,6 +91,7 @@ intelInitExtensions(struct gl_context *ctx)
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;
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
@@ -38,6 +38,7 @@
#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
@@ -190,7 +191,15 @@ intel_miptree_create(struct intel_context *intel,
{
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 &&
@@ -237,6 +246,7 @@ intel_miptree_create(struct intel_context *intel,
return NULL;
}
+ mt->wraps_etc1 = wraps_etc1;
mt->region = intel_region_alloc(intel->intelScreen,
tiling,
mt->cpp,
@@ -1049,6 +1059,60 @@ intel_miptree_unmap_s8(struct intel_context *intel,
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.
@@ -1225,6 +1289,8 @@ intel_miptree_map(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->stencil_mt) {
intel_miptree_map_depthstencil(intel, mt, map, level, slice);
} else if (intel->has_llc &&
@@ -1261,6 +1327,8 @@ intel_miptree_unmap(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->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 74fcc796cf5..2fb5775c02f 100644
--- a/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/intel/intel_mipmap_tree.h
@@ -190,6 +190,9 @@ struct intel_mipmap_tree
* 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;