summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mesa/drivers/dri/i915/Makefile30
-rw-r--r--src/mesa/drivers/dri/i915/i830_tex.c4
-rw-r--r--src/mesa/drivers/dri/i915/i830_texstate.c22
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.c43
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.h31
-rw-r--r--src/mesa/drivers/dri/i915/i915_metaops.c2
-rw-r--r--src/mesa/drivers/dri/i915/i915_tex.c83
-rw-r--r--src/mesa/drivers/dri/i915/i915_tex_layout.c330
-rw-r--r--src/mesa/drivers/dri/i915/i915_texstate.c983
-rw-r--r--src/mesa/drivers/dri/i915/i915_vtbl.c13
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.c22
-rw-r--r--src/mesa/drivers/dri/i915/intel_context.h73
-rw-r--r--src/mesa/drivers/dri/i915/intel_ioctl.c28
-rw-r--r--src/mesa/drivers/dri/i915/intel_pixel.c4
-rw-r--r--src/mesa/drivers/dri/i915/intel_screen.c4
-rw-r--r--src/mesa/drivers/dri/i915/intel_tex.c843
-rw-r--r--src/mesa/drivers/dri/i915/intel_tex.h52
-rw-r--r--src/mesa/drivers/dri/i915/intel_tex_format.c145
-rw-r--r--src/mesa/drivers/dri/i915/intel_tex_image.c315
-rw-r--r--src/mesa/drivers/dri/i915/intel_tex_subimage.c115
-rw-r--r--src/mesa/drivers/dri/i915/intel_tex_validate.c198
21 files changed, 1516 insertions, 1824 deletions
diff --git a/src/mesa/drivers/dri/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile
index 846acd32f7..fecb41e3d8 100644
--- a/src/mesa/drivers/dri/i915/Makefile
+++ b/src/mesa/drivers/dri/i915/Makefile
@@ -6,23 +6,24 @@ LIBNAME = i915_dri.so
DRIVER_SOURCES = \
bufmgr_fake.c \
+ intel_regions.c \
+ intel_mipmap_tree.c \
+ i915_tex_layout.c \
+ intel_tex_image.c \
+ intel_tex_subimage.c \
+ intel_tex_validate.c \
+ intel_tex_format.c \
+ intel_tex.c \
+ i915_tex.c \
+ i915_texstate.c \
i915_context.c \
i915_debug.c \
i915_fragprog.c \
i915_metaops.c \
i915_program.c \
i915_state.c \
- i915_tex.c \
i915_texprog.c \
- i915_texstate.c \
i915_vtbl.c \
- i830_context.c \
- i830_metaops.c \
- i830_state.c \
- i830_texblend.c \
- i830_tex.c \
- i830_texstate.c \
- i830_vtbl.c \
intel_batchbuffer.c \
intel_context.c \
intel_ioctl.c \
@@ -31,9 +32,18 @@ DRIVER_SOURCES = \
intel_screen.c \
intel_span.c \
intel_state.c \
- intel_tex.c \
intel_tris.c
+
+DISABLED = \
+ i830_context.c \
+ i830_metaops.c \
+ i830_state.c \
+ i830_texblend.c \
+ i830_tex.c \
+ i830_texstate.c \
+ i830_vtbl.c
+
C_SOURCES = \
$(COMMON_SOURCES) \
$(MINIGLX_SOURCES) \
diff --git a/src/mesa/drivers/dri/i915/i830_tex.c b/src/mesa/drivers/dri/i915/i830_tex.c
index d56a4df8bb..56b2b92bde 100644
--- a/src/mesa/drivers/dri/i915/i830_tex.c
+++ b/src/mesa/drivers/dri/i915/i830_tex.c
@@ -200,7 +200,7 @@ intelTextureObjectPtr i830AllocTexObj( struct gl_texture_object *texObj )
texObj->DriverData = t;
t->intel.base.tObj = texObj;
- t->intel.dirty = I830_UPLOAD_TEX_ALL;
+ t->intel.dirty = ~0;
make_empty_list( &t->intel.base );
t->Setup[I830_TEXREG_TM0LI] = 0; /* not used */
@@ -268,7 +268,7 @@ static void i830TexParameter( GLcontext *ctx, GLenum target,
return;
}
- t->intel.dirty = I830_UPLOAD_TEX_ALL;
+ t->intel.dirty = ~0;
}
diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c
index ba972dac8f..85da0ee281 100644
--- a/src/mesa/drivers/dri/i915/i830_texstate.c
+++ b/src/mesa/drivers/dri/i915/i830_texstate.c
@@ -246,7 +246,7 @@ static GLboolean i830SetTexImages( i830ContextPtr i830,
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK;
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK;
t->Setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT;
- t->intel.dirty = I830_UPLOAD_TEX_ALL;
+ t->intel.dirty = ~0;
return intelUploadTexImages( &i830->intel, &t->intel, 0 );
}
@@ -259,11 +259,7 @@ static void i830_import_tex_unit( i830ContextPtr i830,
if(INTEL_DEBUG&DEBUG_TEXTURE)
fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit);
- if (i830->intel.CurrentTexObj[unit])
- i830->intel.CurrentTexObj[unit]->base.bound &= ~(1U << unit);
-
i830->intel.CurrentTexObj[unit] = (intelTextureObjectPtr)t;
- t->intel.base.bound |= (1 << unit);
I830_STATECHANGE( i830, I830_UPLOAD_TEX(unit) );
@@ -285,7 +281,7 @@ static void i830_import_tex_unit( i830ContextPtr i830,
i830->state.Tex[unit][I830_TEXREG_CUBE] = t->Setup[I830_TEXREG_CUBE];
i830->state.Tex[unit][I830_TEXREG_MCS] |= MAP_UNIT(unit);
- t->intel.dirty &= ~I830_UPLOAD_TEX(unit);
+ t->intel.dirty &= ~(1<<unit); /* This is broken! */
}
@@ -317,7 +313,7 @@ static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit )
* time.
*/
if (i830->intel.CurrentTexObj[unit] != &t->intel ||
- (t->intel.dirty & I830_UPLOAD_TEX(unit))) {
+ (t->intel.dirty & (1<<unit))) {
i830_import_tex_unit( i830, t, unit);
}
@@ -419,14 +415,10 @@ static GLboolean disable_tex( GLcontext *ctx, GLuint unit )
* one if nothing is enabled.
*/
- if ( i830->intel.CurrentTexObj[unit] != NULL ) {
- /* The old texture is no longer bound to this texture unit.
- * Mark it as such.
- */
-
- i830->intel.CurrentTexObj[unit]->base.bound &= ~(1U << 0);
- i830->intel.CurrentTexObj[unit] = NULL;
- }
+ /* The old texture is no longer bound to this texture unit.
+ * Mark it as such.
+ */
+ i830->intel.CurrentTexObj[unit] = NULL;
return GL_TRUE;
}
diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c
index cd0eaf2470..817a7bb5f1 100644
--- a/src/mesa/drivers/dri/i915/i915_context.c
+++ b/src/mesa/drivers/dri/i915/i915_context.c
@@ -41,6 +41,8 @@
#include "utils.h"
#include "i915_reg.h"
+#include "bufmgr.h"
+
/***************************************
* Mesa's Driver Functions
***************************************/
@@ -119,33 +121,22 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
ctx->Const.MaxTextureImageUnits = I915_TEX_UNITS;
ctx->Const.MaxTextureCoordUnits = I915_TEX_UNITS;
- intel->nr_heaps = 1;
- intel->texture_heaps[0] =
- driCreateTextureHeap( 0, intel,
- intel->intelScreen->tex.size,
- 12,
- I830_NR_TEX_REGIONS,
- intel->sarea->texList,
- & intel->sarea->texAge,
- & intel->swapped,
- sizeof( struct i915_texture_object ),
- (destroy_texture_object_t *)intelDestroyTexObj );
-
- /* FIXME: driCalculateMaxTextureLevels assumes that mipmaps are
- * tightly packed, but they're not in Intel graphics
- * hardware.
+ intel->bm = bm_fake_intel_Attach( intel );
+
+ bmInitPool(intel->bm,
+ 0,
+ 0, /* low offset */
+ intel->intelScreen->tex.size, /* high offset */
+ intel->intelScreen->tex.map); /* virtual base */
+
+ /* AGP allocation won't work:
*/
- ctx->Const.MaxTextureUnits = 1;
- driCalculateMaxTextureLevels( intel->texture_heaps,
- intel->nr_heaps,
- &intel->ctx.Const,
- 4,
- 11, /* max 2D texture size is 2048x2048 */
- 8, /* 3D texture */
- 11, /* cube texture. */
- 11, /* rect texture */
- 12,
- GL_FALSE );
+ intel->intelScreen->allow_batchbuffer = GL_FALSE;
+
+ ctx->Const.MaxTextureLevels = 11;
+ ctx->Const.Max3DTextureLevels = 8;
+ ctx->Const.MaxCubeTextureLevels = 11;
+ ctx->Const.MaxTextureRectSize = (1<<11);
ctx->Const.MaxTextureUnits = I915_TEX_UNITS;
/* GL_ARB_fragment_program limits - don't think Mesa actually
diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h
index 8046277643..fa63d794f9 100644
--- a/src/mesa/drivers/dri/i915/i915_context.h
+++ b/src/mesa/drivers/dri/i915/i915_context.h
@@ -163,8 +163,6 @@ struct i915_fragment_program {
GLuint nr_params;
-
-
/* Helpers for i915_texprog.c:
*/
GLuint src_texture; /* Reg containing sampled texture color,
@@ -185,13 +183,6 @@ struct i915_fragment_program {
-struct i915_texture_object
-{
- struct intel_texture_object intel;
- GLenum lastTarget;
- GLboolean refs_border_color;
- GLuint Setup[I915_TEX_SETUP_SIZE];
-};
#define I915_TEX_UNITS 8
@@ -220,6 +211,8 @@ struct i915_context
GLuint last_ReallyEnabled;
GLuint vertex_fog;
+ GLuint lodbias_ss2[MAX_TEXTURE_UNITS];
+
struct i915_fragment_program tex_program;
struct i915_fragment_program *current_program;
@@ -229,10 +222,6 @@ struct i915_context
typedef struct i915_context *i915ContextPtr;
-typedef struct i915_texture_object *i915TextureObjectPtr;
-
-#define I915_CONTEXT(ctx) ((i915ContextPtr)(ctx))
-
#define I915_STATECHANGE(i915, flag) \
@@ -346,6 +335,22 @@ i915ClearWithTris( intelContextPtr intel, GLbitfield mask,
*/
extern void i915ValidateFragmentProgram( i915ContextPtr i915 );
extern void i915InitFragProgFuncs( struct dd_function_table *functions );
+
+/*======================================================================
+ * Inline conversion functions. These are better-typed than the
+ * macros used previously:
+ */
+static inline struct i915_context *
+i915_context( GLcontext *ctx )
+{
+ return (struct i915_context *)ctx;
+}
+
+
+
+#define I915_CONTEXT(ctx) i915_context(ctx)
+
+
#endif
diff --git a/src/mesa/drivers/dri/i915/i915_metaops.c b/src/mesa/drivers/dri/i915/i915_metaops.c
index a3d22b7bd0..066c6b5ecd 100644
--- a/src/mesa/drivers/dri/i915/i915_metaops.c
+++ b/src/mesa/drivers/dri/i915/i915_metaops.c
@@ -447,7 +447,7 @@ i915ClearWithTris(intelContextPtr intel, GLbitfield mask,
GLboolean all,
GLint cx, GLint cy, GLint cw, GLint ch)
{
- i915ContextPtr i915 = I915_CONTEXT( intel );
+ i915ContextPtr i915 = i915_context( &intel->ctx );
__DRIdrawablePrivate *dPriv = intel->driDrawable;
intelScreenPrivate *screen = intel->intelScreen;
int x0, y0, x1, y1;
diff --git a/src/mesa/drivers/dri/i915/i915_tex.c b/src/mesa/drivers/dri/i915/i915_tex.c
index 4f77833e19..92bc94b8ee 100644
--- a/src/mesa/drivers/dri/i915/i915_tex.c
+++ b/src/mesa/drivers/dri/i915/i915_tex.c
@@ -45,76 +45,10 @@
-
-
-
-/**
- * Allocate space for and load the mesa images into the texture memory block.
- * This will happen before drawing with a new texture, or drawing with a
- * texture after it was swapped out or teximaged again.
- */
-
-intelTextureObjectPtr i915AllocTexObj( struct gl_texture_object *texObj )
-{
- i915TextureObjectPtr t = CALLOC_STRUCT( i915_texture_object );
- if ( !t )
- return NULL;
-
- texObj->DriverData = t;
- t->intel.base.tObj = texObj;
- t->intel.dirty = I915_UPLOAD_TEX_ALL;
- make_empty_list( &t->intel.base );
- return &t->intel;
-}
-
-
-static void i915TexParameter( GLcontext *ctx, GLenum target,
- struct gl_texture_object *tObj,
- GLenum pname, const GLfloat *params )
-{
- i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData;
-
- switch (pname) {
- case GL_TEXTURE_MIN_FILTER:
- case GL_TEXTURE_MAG_FILTER:
- case GL_TEXTURE_MAX_ANISOTROPY_EXT:
- case GL_TEXTURE_WRAP_S:
- case GL_TEXTURE_WRAP_T:
- case GL_TEXTURE_WRAP_R:
- case GL_TEXTURE_BORDER_COLOR:
- t->intel.dirty = I915_UPLOAD_TEX_ALL;
- break;
-
- case GL_TEXTURE_COMPARE_MODE:
- t->intel.dirty = I915_UPLOAD_TEX_ALL;
- break;
- case GL_TEXTURE_COMPARE_FUNC:
- t->intel.dirty = I915_UPLOAD_TEX_ALL;
- break;
-
- case GL_TEXTURE_BASE_LEVEL:
- case GL_TEXTURE_MAX_LEVEL:
- case GL_TEXTURE_MIN_LOD:
- case GL_TEXTURE_MAX_LOD:
- /* The i915 and its successors can do a lot of this without
- * reloading the textures. A project for someone?
- */
- intelFlush( ctx );
- driSwapOutTextureObject( (driTextureObject *) t );
- t->intel.dirty = I915_UPLOAD_TEX_ALL;
- break;
-
- default:
- return;
- }
-}
-
-
static void i915TexEnv( GLcontext *ctx, GLenum target,
GLenum pname, const GLfloat *param )
{
i915ContextPtr i915 = I915_CONTEXT( ctx );
- GLuint unit = ctx->Texture.CurrentUnit;
switch (pname) {
case GL_TEXTURE_ENV_COLOR: /* Should be a tracked param */
@@ -139,13 +73,12 @@ static void i915TexEnv( GLcontext *ctx, GLenum target,
break;
case GL_TEXTURE_LOD_BIAS: {
- int b = (int) ((*param) * 16.0);
+ GLuint unit = ctx->Texture.CurrentUnit;
+ GLint b = (int) ((*param) * 16.0);
if (b > 255) b = 255;
if (b < -256) b = -256;
I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
- i915->state.Tex[unit][I915_TEXREG_SS2] &= ~SS2_LOD_BIAS_MASK;
- i915->state.Tex[unit][I915_TEXREG_SS2] |=
- ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK);
+ i915->lodbias_ss2[unit] = ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK);
break;
}
@@ -156,15 +89,8 @@ static void i915TexEnv( GLcontext *ctx, GLenum target,
static void i915BindTexture( GLcontext *ctx, GLenum target,
- struct gl_texture_object *texObj )
+ struct gl_texture_object *texobj )
{
- i915TextureObjectPtr tex = (i915TextureObjectPtr)texObj->DriverData;
-
- if (tex->lastTarget != texObj->Target) {
- tex->intel.dirty = I915_UPLOAD_TEX_ALL;
- tex->lastTarget = texObj->Target;
- }
-
/* Need this if image format changes between bound textures.
* Could try and shortcircuit by checking for differences in
* state between incoming and outgoing textures:
@@ -178,5 +104,4 @@ void i915InitTextureFuncs( struct dd_function_table *functions )
{
functions->BindTexture = i915BindTexture;
functions->TexEnv = i915TexEnv;
- functions->TexParameter = i915TexParameter;
}
diff --git a/src/mesa/drivers/dri/i915/i915_tex_layout.c b/src/mesa/drivers/dri/i915/i915_tex_layout.c
new file mode 100644
index 0000000000..d79a64ea67
--- /dev/null
+++ b/src/mesa/drivers/dri/i915/i915_tex_layout.c
@@ -0,0 +1,330 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Code to layout images in a mipmap tree for i915 and i945
+ * respectively.
+ */
+
+#include "intel_mipmap_tree.h"
+#include "macros.h"
+
+static GLint initial_offsets[6][2] = { {0,0},
+ {0,2},
+ {1,0},
+ {1,2},
+ {1,1},
+ {1,3} };
+
+
+static GLint step_offsets[6][2] = { {0,2},
+ {0,2},
+ {-1,2},
+ {-1,2},
+ {-1,1},
+ {-1,1} };
+
+static GLuint minify( GLuint d )
+{
+ return MAX2(1, d>>1);
+}
+
+GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
+{
+ GLint i;
+ GLint numLevels = mt->last_level - mt->first_level + 1;
+
+ switch (mt->target) {
+ case GL_TEXTURE_CUBE_MAP: {
+ const GLuint dim = mt->width0;
+ GLuint face;
+
+ /* double pitch for cube layouts */
+ mt->pitch = (dim * mt->cpp * 2 + 3) & ~3;
+ mt->total_height = dim * 4;
+
+ for ( face = 0 ; face < 6 ; face++) {
+ GLuint x = initial_offsets[face][0] * dim;
+ GLuint y = initial_offsets[face][1] * dim;
+ GLuint d = dim;
+
+ for (i = 0; i < numLevels; i++) {
+ mt->offset[face][i].x = x;
+ mt->offset[face][i].y = y;
+ mt->offset[face][i].width = d;
+ mt->offset[face][i].height = d;
+ mt->offset[face][i].depth = 0;
+
+ d >>= 1;
+ assert(d > 0);
+
+ x += step_offsets[face][0] * d;
+ y += step_offsets[face][1] * d;
+ }
+ }
+ break;
+ }
+ case GL_TEXTURE_3D: {
+ GLuint width = mt->width0;
+ GLuint height = mt->height0;
+ GLuint depth = mt->depth0;
+ GLuint tmp_numLevels = MAX2(numLevels, 9);
+
+ /* Calculate the size of a single slice. Hardware demands a
+ * minimum of 8 mipmaps, some of which might ultimately not be
+ * used:
+ */
+ mt->pitch = (mt->width0 * mt->cpp + 3) & ~3;
+ mt->total_height = 0;
+
+ for ( i = 0 ; i < tmp_numLevels ; i++ ) {
+ mt->offset[0][i].x = 0;
+ mt->offset[0][i].y = mt->total_height;
+ mt->offset[0][i].width = width;
+ mt->offset[0][i].height = height;
+ mt->offset[0][i].depth = depth;
+
+ mt->total_height += MAX2(2, height);
+
+ width = minify(width);
+ height = minify(height);
+ depth = minify(depth);
+ }
+
+
+ /* Multiply slice size by texture depth for total size. It's
+ * remarkable how wasteful of memory the i915 texture layouts
+ * are. They are largely fixed in the i945.
+ */
+ mt->depth_pitch = mt->total_height * mt->pitch;
+ mt->total_height *= mt->depth0;
+ break;
+ }
+
+ default: {
+ GLuint width = mt->width0;
+ GLuint height = mt->height0;
+
+ mt->pitch = (mt->width0 * mt->cpp + 3) & ~3;
+ mt->total_height = 0;
+
+ for ( i = 0 ; i < numLevels ; i++ ) {
+ mt->offset[0][i].x = 0;
+ mt->offset[0][i].y = mt->total_height;
+ mt->offset[0][i].height = height;
+ mt->offset[0][i].width = width;
+ mt->offset[0][i].depth = 0;
+
+
+ if (mt->compressed)
+ mt->total_height += MAX2(1, height/4);
+ else
+ mt->total_height += MAX2(2, height);
+
+ width = minify(width);
+ height = minify(height);
+ }
+ break;
+ }
+ }
+
+ return GL_TRUE;
+}
+
+
+GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt )
+{
+ GLint numLevels = mt->last_level - mt->first_level + 1;
+ GLint i;
+
+ switch (mt->target) {
+ case GL_TEXTURE_CUBE_MAP: {
+ const GLuint dim = mt->width0;
+ GLuint face;
+
+ /* Depending on the size of the largest images, pitch can be
+ * determined either by the old-style packing of cubemap faces,
+ * or the final row of 4x4, 2x2 and 1x1 faces below this.
+ */
+ if (dim > 32)
+ mt->pitch = (dim * mt->cpp * 2 + 3) & ~3;
+ else
+ mt->pitch = 14 * 8 * mt->cpp;
+
+ mt->total_height = dim * 4 + 4;
+
+
+ for ( face = 0 ; face < 6 ; face++) {
+ GLuint x = initial_offsets[face][0] * dim;
+ GLuint y = initial_offsets[face][1] * dim;
+ GLuint d = dim;
+
+ if (dim == 4 && face >= 4) {
+ y = mt->total_height - 4;
+ x = (face - 4) * 8;
+ }
+ else if (dim < 4) {
+ y = mt->total_height - 4;
+ x = face * 8;
+ }
+
+ for (i = 0; i < numLevels; i++) {
+ mt->offset[face][i].x = x;
+ mt->offset[face][i].y = y;
+ mt->offset[face][i].width = d;
+ mt->offset[face][i].height = d;
+ mt->offset[face][i].depth = 0;
+
+ d >>= 1;
+ assert(d > 0);
+
+ switch (d) {
+ case 4:
+ switch (face) {
+ case FACE_POS_X:
+ case FACE_NEG_X:
+ x += step_offsets[face][0] * d;
+ y += step_offsets[face][1] * d;
+ break;
+ case FACE_POS_Y:
+ case FACE_NEG_Y:
+ y += 12;
+ x -= 8;
+ break;
+ case FACE_POS_Z:
+ case FACE_NEG_Z:
+ y = mt->total_height - 4;
+ x = (face - 4) * 8;
+ break;
+ }
+
+ case 2:
+ y = mt->total_height - 4;
+ x = 16 + face * 8;
+ break;
+
+ case 1:
+ x += 48;
+ break;
+
+ default:
+ x += step_offsets[face][0] * d;
+ y += step_offsets[face][1] * d;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ case GL_TEXTURE_3D: {
+ GLuint width = mt->width0;
+ GLuint height = mt->height0;
+ GLuint depth = mt->depth0;
+ GLuint depth_pack_pitch;
+ GLuint depth_packing = 0;
+
+ mt->pitch = (mt->width0 * mt->cpp + 3) & ~3;
+ mt->total_height = 0;
+
+ depth_pack_pitch = mt->pitch;
+
+ for ( i = 0 ; i < numLevels ; i++ ) {
+
+ mt->offset[0][i].x = 0;
+ mt->offset[0][i].y = mt->total_height;
+ mt->offset[0][i].width = width;
+ mt->offset[0][i].height = height;
+ mt->offset[0][i].depth = depth;
+
+ mt->total_height += MAX2(2, height) * MAX2((depth >> depth_packing), 1);
+
+ /* When alignment dominates, can't increase depth packing?
+ * Or does pitch grow??? What are the alignment constraints,
+ * anyway?
+ */
+ if (depth_pack_pitch > 4) {
+ depth_packing++;
+ depth_pack_pitch <<= 2; /* KW: is this right?? */
+ }
+
+ width = minify(width);
+ height = minify(height);
+ depth = minify(depth);
+
+ /* XXX: Not sure how 3d textures work on i945 - where did
+ * t->depth_pitch get set in the old code. Did it ever work?
+ * Fix up later.
+ */
+ }
+ break;
+ }
+
+ default: {
+ GLuint x = 0;
+ GLuint y = 0;
+ GLuint width = mt->width0;
+ GLuint height = mt->height0;
+
+ mt->pitch = (mt->width0 * mt->cpp + 3) & ~3;
+ mt->total_height = 0;
+
+ for ( i = 0 ; i < numLevels ; i++ ) {
+ mt->offset[0][i].x = x;
+ mt->offset[0][i].y = y;
+ mt->offset[0][i].height = height;
+ mt->offset[0][i].width = width;
+ mt->offset[0][i].depth = 0;
+
+
+ /* LPT change: step right after second mipmap.
+ */
+ if (i == 1)
+ x += mt->pitch / (2 * mt->cpp);
+ else {
+ GLuint img_height;
+
+ if (mt->compressed)
+ img_height = MAX2(1, height/4);
+ else
+ img_height = MAX2(2, height);
+
+ y += img_height;
+ }
+
+ /* Because the images are packed better, the final offset
+ * might not be the maximal one:
+ */
+ mt->total_height = MAX2(mt->total_height, y);
+
+ width = minify(width);
+ height = minify(height);
+ }
+ break;
+ }
+ }
+ return GL_TRUE;
+}
+
diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c
index efd6fc9450..410890f6da 100644
--- a/src/mesa/drivers/dri/i915/i915_texstate.c
+++ b/src/mesa/drivers/dri/i915/i915_texstate.c
@@ -25,500 +25,61 @@
*
**************************************************************************/
-#include "glheader.h"
-#include "macros.h"
#include "mtypes.h"
-#include "simple_list.h"
#include "enums.h"
#include "texformat.h"
-#include "texstore.h"
-#include "mm.h"
-
-#include "intel_screen.h"
-#include "intel_ioctl.h"
+#include "intel_mipmap_tree.h"
#include "intel_tex.h"
#include "i915_context.h"
#include "i915_reg.h"
-static GLint initial_offsets[6][2] = { {0,0},
- {0,2},
- {1,0},
- {1,2},
- {1,1},
- {1,3} };
-
-
-static GLint step_offsets[6][2] = { {0,2},
- {0,2},
- {-1,2},
- {-1,2},
- {-1,1},
- {-1,1} };
-
-
-#define I915_TEX_UNIT_ENABLED(unit) (1<<unit)
-
-static void i915LayoutTextureImages( i915ContextPtr i915,
- struct gl_texture_object *tObj )
-{
- const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
- i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData;
- GLint firstLevel, lastLevel, numLevels;
- GLint i, total_height, pitch;
-
- /* Compute which mipmap levels we really want to send to the hardware.
- */
- driCalculateTextureFirstLastLevel( (driTextureObject *) t );
-
- /* Figure out the amount of memory required to hold all the mipmap
- * levels. Choose the smallest pitch to accomodate the largest
- * mipmap:
- */
- firstLevel = t->intel.base.firstLevel;
- lastLevel = t->intel.base.lastLevel;
- numLevels = lastLevel - firstLevel + 1;
-
-
-
- /* All images must be loaded at this pitch. Count the number of
- * lines required:
- */
- switch (tObj->Target) {
- case GL_TEXTURE_CUBE_MAP: {
- const GLuint dim = tObj->Image[0][firstLevel]->Width;
- GLuint face;
-
- pitch = dim * t->intel.texelBytes;
- pitch *= 2; /* double pitch for cube layouts */
- pitch = (pitch + 3) & ~3;
-
- total_height = dim * 4;
-
- for ( face = 0 ; face < 6 ; face++) {
- GLuint x = initial_offsets[face][0] * dim;
- GLuint y = initial_offsets[face][1] * dim;
- GLuint d = dim;
-
- t->intel.base.dirty_images[face] = ~0;
-
- assert(tObj->Image[face][firstLevel]->Width == dim);
- assert(tObj->Image[face][firstLevel]->Height == dim);
-
- for (i = 0; i < numLevels; i++) {
- t->intel.image[face][i].image = tObj->Image[face][firstLevel + i];
- if (!t->intel.image[face][i].image) {
- fprintf(stderr, "no image %d %d\n", face, i);
- break; /* can't happen */
- }
-
- t->intel.image[face][i].offset =
- y * pitch + x * t->intel.texelBytes;
- t->intel.image[face][i].internalFormat = baseImage->_BaseFormat;
-
- d >>= 1;
- x += step_offsets[face][0] * d;
- y += step_offsets[face][1] * d;
- }
- }
- break;
- }
- case GL_TEXTURE_3D: {
- GLuint virtual_height;
- GLuint tmp_numLevels = numLevels;
- pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
- pitch = (pitch + 3) & ~3;
- t->intel.base.dirty_images[0] = ~0;
-
- /* Calculate the size of a single slice. Hardware demands a
- * minimum of 8 mipmaps, some of which might ultimately not be
- * used:
- */
- if (tmp_numLevels < 9)
- tmp_numLevels = 9;
-
- virtual_height = tObj->Image[0][firstLevel]->Height;
-
- for ( total_height = i = 0 ; i < tmp_numLevels ; i++ ) {
- t->intel.image[0][i].image = tObj->Image[0][firstLevel + i];
- if (t->intel.image[0][i].image) {
- t->intel.image[0][i].offset = total_height * pitch;
- t->intel.image[0][i].internalFormat = baseImage->_BaseFormat;
- }
-
- total_height += MAX2(2, virtual_height);
- virtual_height >>= 1;
- }
-
- t->intel.depth_pitch = total_height * pitch;
-
- /* Multiply slice size by texture depth for total size. It's
- * remarkable how wasteful of memory all the i8x0 texture
- * layouts are.
- */
- total_height *= t->intel.image[0][0].image->Depth;
- break;
- }
- default:
- pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
- pitch = (pitch + 3) & ~3;
- t->intel.base.dirty_images[0] = ~0;
-
- for ( total_height = i = 0 ; i < numLevels ; i++ ) {
- t->intel.image[0][i].image = tObj->Image[0][firstLevel + i];
- if (!t->intel.image[0][i].image)
- break;
-
- t->intel.image[0][i].offset = total_height * pitch;
- t->intel.image[0][i].internalFormat = baseImage->_BaseFormat;
- if (t->intel.image[0][i].image->IsCompressed)
- {
- if (t->intel.image[0][i].image->Height > 4)
- total_height += t->intel.image[0][i].image->Height/4;
- else
- total_height += 1;
- }
- else
- total_height += MAX2(2, t->intel.image[0][i].image->Height);
- }
- break;
- }
-
- t->intel.Pitch = pitch;
- t->intel.base.totalSize = total_height*pitch;
- t->intel.max_level = numLevels-1;
-}
-
-static void i945LayoutTextureImages( i915ContextPtr i915,
- struct gl_texture_object *tObj )
+static GLuint translate_texture_format( GLuint mesa_format )
{
- const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
- i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData;
- GLint firstLevel, lastLevel, numLevels;
- GLint i, total_height, pitch, sz, max_offset = 0, offset;
-
-
- /* Compute which mipmap levels we really want to send to the hardware.
- */
- driCalculateTextureFirstLastLevel( (driTextureObject *) t );
-
- /* Figure out the amount of memory required to hold all the mipmap
- * levels. Choose the smallest pitch to accomodate the largest
- * mipmap:
- */
- firstLevel = t->intel.base.firstLevel;
- lastLevel = t->intel.base.lastLevel;
- numLevels = lastLevel - firstLevel + 1;
-
-
-
- /* All images must be loaded at this pitch. Count the number of
- * lines required:
- */
- switch (tObj->Target) {
- case GL_TEXTURE_CUBE_MAP: {
- const GLuint dim = tObj->Image[0][firstLevel]->Width;
- GLuint face;
-
- /* Depending on the size of the largest images, pitch can be
- * determined either by the old-style packing of cubemap faces,
- * or the final row of 4x4, 2x2 and 1x1 faces below this.
- */
- if (dim > 32) {
- pitch = dim * t->intel.texelBytes;
- pitch *= 2; /* double pitch for cube layouts */
- pitch = (pitch + 3) & ~3;
- }
- else {
- pitch = 14 * 8 * t->intel.texelBytes; /* determined by row of
- * little maps at
- * bottom */
- }
-
- total_height = dim * 4 + 4;
-
- for ( face = 0 ; face < 6 ; face++) {
- GLuint x = initial_offsets[face][0] * dim;
- GLuint y = initial_offsets[face][1] * dim;
- GLuint d = dim;
-
- if (dim == 4 && face >= 4) {
- y = total_height - 4;
- x = (face - 4) * 8;
- }
- else if (dim < 4) {
- y = total_height - 4;
- x = face * 8;
- }
-
- t->intel.base.dirty_images[face] = ~0;
-
- assert(tObj->Image[face][firstLevel]->Width == dim);
- assert(tObj->Image[face][firstLevel]->Height == dim);
-
- for (i = 0; i < numLevels; i++) {
-
-
- t->intel.image[face][i].image = tObj->Image[face][firstLevel + i];
- assert(t->intel.image[face][i].image);
-
- t->intel.image[face][i].offset =
- y * pitch + x * t->intel.texelBytes;
- t->intel.image[face][i].internalFormat = baseImage->_BaseFormat;
-
- d >>= 1;
-
- switch (d) {
- case 4:
- switch (face) {
- case FACE_POS_X:
- case FACE_NEG_X:
- x += step_offsets[face][0] * d;
- y += step_offsets[face][1] * d;
- break;
- case FACE_POS_Y:
- case FACE_NEG_Y:
- y += 12;
- x -= 8;
- break;
- case FACE_POS_Z:
- case FACE_NEG_Z:
- y = total_height - 4;
- x = (face - 4) * 8;
- break;
- }
-
- case 2:
- y = total_height - 4;
- x = 16 + face * 8;
- break;
-
- case 1:
- x += 48;
- break;
-
- default:
- x += step_offsets[face][0] * d;
- y += step_offsets[face][1] * d;
- break;
- }
- }
- }
- max_offset = total_height * pitch;
- break;
- }
- case GL_TEXTURE_3D: {
- GLuint depth_packing = 0, depth_pack_pitch;
- GLuint tmp_numLevels = numLevels;
- pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
- pitch = (pitch + 3) & ~3;
- depth_pack_pitch = pitch;
-
- t->intel.base.dirty_images[0] = ~0;
-
-
- for ( total_height = i = 0 ; i < tmp_numLevels ; i++ ) {
- t->intel.image[0][i].image = tObj->Image[0][firstLevel + i];
- if (!t->intel.image[0][i].image)
- break;
-
-
- t->intel.image[0][i].offset = total_height * pitch;
- t->intel.image[0][i].internalFormat = baseImage->_BaseFormat;
-
-
-
- total_height += MAX2(2, t->intel.image[0][i].image->Height) *
- MAX2((t->intel.image[0][i].image->Depth >> depth_packing), 1);
-
- /* When alignment dominates, can't increase depth packing?
- * Or does pitch grow??? What are the alignment constraints,
- * anyway?
- */
- if (depth_pack_pitch > 4) {
- depth_packing++;
- depth_pack_pitch <<= 2;
- }
- }
-
- max_offset = total_height * pitch;
- break;
- }
- default:
- pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes;
- pitch = (pitch + 3) & ~3;
- t->intel.base.dirty_images[0] = ~0;
- max_offset = 0;
-
- for ( offset = i = 0 ; i < numLevels ; i++ ) {
- t->intel.image[0][i].image = tObj->Image[0][firstLevel + i];
- if (!t->intel.image[0][i].image)
- break;
-
- t->intel.image[0][i].offset = offset;
- t->intel.image[0][i].internalFormat = baseImage->_BaseFormat;
-
- if (t->intel.image[0][i].image->IsCompressed)
- sz = MAX2(1, t->intel.image[0][i].image->Height/4) * pitch;
- else
- sz = MAX2(2, t->intel.image[0][i].image->Height) * pitch;
-
- /* Because the images are packed better, the final offset
- * might not be the maximal one:
- */
- max_offset = MAX2(max_offset, offset + sz);
-
- /* LPT change: step right after second mipmap.
- */
- if (i == 1)
- offset += pitch / 2;
- else
- offset += sz;
-
- }
- break;
- }
-
- t->intel.Pitch = pitch;
- t->intel.base.totalSize = max_offset;
- t->intel.max_level = numLevels-1;
-}
-
-
-
-
-static void i915SetTexImages( i915ContextPtr i915,
- struct gl_texture_object *tObj )
-{
- GLuint textureFormat;
- i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData;
- const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
- GLint ss2 = 0;
-
- switch( baseImage->TexFormat->MesaFormat ) {
+ switch (mesa_format) {
case MESA_FORMAT_L8:
- t->intel.texelBytes = 1;
- textureFormat = MAPSURF_8BIT | MT_8BIT_L8;
- break;
-
+ return MAPSURF_8BIT | MT_8BIT_L8;
case MESA_FORMAT_I8:
- t->intel.texelBytes = 1;
- textureFormat = MAPSURF_8BIT | MT_8BIT_I8;
- break;
-
+ return MAPSURF_8BIT | MT_8BIT_I8;
case MESA_FORMAT_A8:
- t->intel.texelBytes = 1;
- textureFormat = MAPSURF_8BIT | MT_8BIT_A8;
- break;
-
+ return MAPSURF_8BIT | MT_8BIT_A8;
case MESA_FORMAT_AL88:
- t->intel.texelBytes = 2;
- textureFormat = MAPSURF_16BIT | MT_16BIT_AY88;
- break;
-
+ return MAPSURF_16BIT | MT_16BIT_AY88;
case MESA_FORMAT_RGB565:
- t->intel.texelBytes = 2;
- textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
- break;
-
+ return MAPSURF_16BIT | MT_16BIT_RGB565;
case MESA_FORMAT_ARGB1555:
- t->intel.texelBytes = 2;
- textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555;
- break;
-
+ return MAPSURF_16BIT | MT_16BIT_ARGB1555;
case MESA_FORMAT_ARGB4444:
- t->intel.texelBytes = 2;
- textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB4444;
- break;
-
+ return MAPSURF_16BIT | MT_16BIT_ARGB4444;
case MESA_FORMAT_ARGB8888:
- t->intel.texelBytes = 4;
- textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
- break;
-
+ return MAPSURF_32BIT | MT_32BIT_ARGB8888;
case MESA_FORMAT_YCBCR_REV:
- t->intel.texelBytes = 2;
- textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL);
- ss2 |= SS2_COLORSPACE_CONVERSION;
- break;
-
+ return (MAPSURF_422 | MT_422_YCRCB_NORMAL);
case MESA_FORMAT_YCBCR:
- t->intel.texelBytes = 2;
- textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY);
- ss2 |= SS2_COLORSPACE_CONVERSION;
- break;
-
+ return (MAPSURF_422 | MT_422_YCRCB_SWAPY);
case MESA_FORMAT_RGB_FXT1:
case MESA_FORMAT_RGBA_FXT1:
- t->intel.texelBytes = 2;
- textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1);
- break;
-
+ return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1);
case MESA_FORMAT_DEPTH_COMPONENT16:
- t->intel.texelBytes = 2;
- textureFormat = (MAPSURF_16BIT | MT_16BIT_L16);
- break;
-
+ return (MAPSURF_16BIT | MT_16BIT_L16);
case MESA_FORMAT_RGBA_DXT1:
case MESA_FORMAT_RGB_DXT1:
- /*
- * DXTn pitches are Width/4 * blocksize in bytes
- * for DXT1: blocksize=8 so Width/4*8 = Width * 2
- * for DXT3/5: blocksize=16 so Width/4*16 = Width * 4
- */
- t->intel.texelBytes = 2;
- textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1);
- break;
-
+ return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1);
case MESA_FORMAT_RGBA_DXT3:
- t->intel.texelBytes = 4;
- textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3);
- break;
-
+ return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3);
case MESA_FORMAT_RGBA_DXT5:
- t->intel.texelBytes = 4;
- textureFormat = (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5);
- break;
-
-#if 0
- case MESA_FORMAT_DEPTH_COMPONENT_X8Z24:
- t->intel.texelBytes = 4;
- textureFormat = (MAPSURF_32BIT | MT_32BIT_xL824);
- break;
-#endif
-
+ return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5);
default:
fprintf(stderr, "%s: bad image format %x\n", __FUNCTION__,
- baseImage->TexFormat->MesaFormat);
+ mesa_format);
abort();
+ return 0;
}
+}
- if (i915->intel.intelScreen->deviceID == PCI_CHIP_I945_G)
- i945LayoutTextureImages( i915, tObj );
- else
- i915LayoutTextureImages( i915, tObj );
-
- t->Setup[I915_TEXREG_MS3] =
- (((tObj->Image[0][t->intel.base.firstLevel]->Height - 1) << MS3_HEIGHT_SHIFT) |
- ((tObj->Image[0][t->intel.base.firstLevel]->Width - 1) << MS3_WIDTH_SHIFT) |
- textureFormat |
- MS3_USE_FENCE_REGS);
-
- t->Setup[I915_TEXREG_MS4] =
- ((((t->intel.Pitch / 4) - 1) << MS4_PITCH_SHIFT) |
- MS4_CUBE_FACE_ENA_MASK |
- (((t->intel.max_level * 4)) << MS4_MAX_LOD_SHIFT) |
- ((tObj->Image[0][t->intel.base.firstLevel]->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT));
-
- t->Setup[I915_TEXREG_SS2] &= ~(SS2_COLORSPACE_CONVERSION);
- t->Setup[I915_TEXREG_SS2] |= ss2;
-
- t->intel.dirty = I915_UPLOAD_TEX_ALL;
-
-}
/* The i915 (and related graphics cores) do not support GL_CLAMP. The
@@ -528,383 +89,192 @@ static void i915SetTexImages( i915ContextPtr i915,
static GLuint translate_wrap_mode( GLenum wrap )
{
switch( wrap ) {
- case GL_REPEAT: return TEXCOORDMODE_WRAP;
- case GL_CLAMP: return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */
- case GL_CLAMP_TO_EDGE: return TEXCOORDMODE_CLAMP_EDGE;
- case GL_CLAMP_TO_BORDER: return TEXCOORDMODE_CLAMP_BORDER;
- case GL_MIRRORED_REPEAT: return TEXCOORDMODE_MIRROR;
- default: return TEXCOORDMODE_WRAP;
- }
-}
-
-
-/**
- */
-static void i915ImportTexObjState( struct gl_texture_object *texObj )
-{
- i915TextureObjectPtr t = (i915TextureObjectPtr)texObj->DriverData;
- int minFilt = 0, mipFilt = 0, magFilt = 0, shadow = 0;
-
- if(INTEL_DEBUG&DEBUG_DRI)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- switch (texObj->MinFilter) {
- case GL_NEAREST:
- minFilt = FILTER_NEAREST;
- mipFilt = MIPFILTER_NONE;
- break;
- case GL_LINEAR:
- minFilt = FILTER_LINEAR;
- mipFilt = MIPFILTER_NONE;
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- minFilt = FILTER_NEAREST;
- mipFilt = MIPFILTER_NEAREST;
- break;
- case GL_LINEAR_MIPMAP_NEAREST:
- minFilt = FILTER_LINEAR;
- mipFilt = MIPFILTER_NEAREST;
- break;
- case GL_NEAREST_MIPMAP_LINEAR:
- minFilt = FILTER_NEAREST;
- mipFilt = MIPFILTER_LINEAR;
- break;
- case GL_LINEAR_MIPMAP_LINEAR:
- minFilt = FILTER_LINEAR;
- mipFilt = MIPFILTER_LINEAR;
- break;
- default:
- break;
- }
-
- if ( texObj->MaxAnisotropy > 1.0 ) {
- minFilt = FILTER_ANISOTROPIC;
- magFilt = FILTER_ANISOTROPIC;
- }
- else {
- switch (texObj->MagFilter) {
- case GL_NEAREST:
- magFilt = FILTER_NEAREST;
- break;
- case GL_LINEAR:
- magFilt = FILTER_LINEAR;
- break;
- default:
- break;
- }
- }
-
- if (texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB &&
- texObj->Target != GL_TEXTURE_3D) {
-
- shadow = SS2_SHADOW_ENABLE;
- shadow |= intel_translate_compare_func( texObj->CompareFunc );
-
- minFilt = FILTER_4X4_FLAT;
- magFilt = FILTER_4X4_FLAT;
- }
-
-
- t->Setup[I915_TEXREG_SS2] &= ~(SS2_MIN_FILTER_MASK |
- SS2_MIP_FILTER_MASK |
- SS2_MAG_FILTER_MASK |
- SS2_SHADOW_ENABLE |
- SS2_SHADOW_FUNC_MASK);
- t->Setup[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) |
- (mipFilt << SS2_MIP_FILTER_SHIFT) |
- (magFilt << SS2_MAG_FILTER_SHIFT) |
- shadow);
-
- {
- GLuint ss3 = t->Setup[I915_TEXREG_SS3] & ~(SS3_TCX_ADDR_MODE_MASK |
- SS3_TCY_ADDR_MODE_MASK |
- SS3_TCZ_ADDR_MODE_MASK);
- GLenum ws = texObj->WrapS;
- GLenum wt = texObj->WrapT;
- GLenum wr = texObj->WrapR;
-
- t->refs_border_color = 0;
-
- if (texObj->Target == GL_TEXTURE_3D &&
- (texObj->MinFilter != GL_NEAREST ||
- texObj->MagFilter != GL_NEAREST)) {
-
- /* Try to mimic GL_CLAMP functionality a little better -
- * switch to CLAMP_TO_BORDER whenever a non-NEAREST filter is
- * in use. Only do this for 3D textures at the moment --
- * doing it universally would fix the conform texbc.c
- * failure, though.
- */
- if (ws == GL_CLAMP) ws = GL_CLAMP_TO_BORDER;
- if (wt == GL_CLAMP) wt = GL_CLAMP_TO_BORDER;
- if (wr == GL_CLAMP) wr = GL_CLAMP_TO_BORDER;
-
- /* 3D textures don't seem to respect the border color.
- * Fallback if there's ever a danger that they might refer to
- * it.
- */
- if (ws == GL_CLAMP_TO_BORDER) t->refs_border_color = 1;
- if (wt == GL_CLAMP_TO_BORDER) t->refs_border_color = 1;
- if (wr == GL_CLAMP_TO_BORDER) t->refs_border_color = 1;
- }
-
- ss3 |= translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT;
- ss3 |= translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT;
- ss3 |= translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT;
-
- if (ss3 != t->Setup[I915_TEXREG_SS3]) {
- t->intel.dirty = I915_UPLOAD_TEX_ALL;
- t->Setup[I915_TEXREG_SS3] = ss3;
- }
- }
-
- {
- const GLubyte *color = texObj->_BorderChan;
-
- t->Setup[I915_TEXREG_SS4] = INTEL_PACKCOLOR8888(color[0],color[1],
- color[2],color[3]);
+ case GL_REPEAT:
+ return TEXCOORDMODE_WRAP;
+ case GL_CLAMP:
+ return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */
+ case GL_CLAMP_TO_EDGE:
+ return TEXCOORDMODE_CLAMP_EDGE;
+ case GL_CLAMP_TO_BORDER:
+ return TEXCOORDMODE_CLAMP_BORDER;
+ case GL_MIRRORED_REPEAT:
+ return TEXCOORDMODE_MIRROR;
+ default:
+ return TEXCOORDMODE_WRAP;
}
}
-static void i915_import_tex_unit( i915ContextPtr i915,
- i915TextureObjectPtr t,
- GLuint unit )
+/* Recalculate all state from scratch. Perhaps not the most
+ * efficient, but this has gotten complex enough that we need
+ * something which is understandable and reliable.
+ */
+static GLboolean i915_update_tex_unit( GLcontext *ctx,
+ GLuint unit,
+ GLuint ss3 )
{
+ struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
+ struct intel_texture_object *intelObj = intel_texture_object(tObj);
+ struct i915_context *i915 = i915_context(ctx);
GLuint state[I915_TEX_SETUP_SIZE];
+ struct gl_texture_image *firstImage;
+ GLuint firstImageOffset;
- if(INTEL_DEBUG&DEBUG_TEXTURE)
- fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit);
-
- if (i915->intel.CurrentTexObj[unit])
- i915->intel.CurrentTexObj[unit]->base.bound &= ~(1U << unit);
-
- i915->intel.CurrentTexObj[unit] = (intelTextureObjectPtr)t;
- t->intel.base.bound |= (1 << unit);
-
- if (t->intel.dirty & I915_UPLOAD_TEX(unit)) {
- i915ImportTexObjState( t->intel.base.tObj );
- t->intel.dirty &= ~I915_UPLOAD_TEX(unit);
- }
-
- state[I915_TEXREG_MS2] = t->intel.TextureOffset;
- state[I915_TEXREG_MS3] = t->Setup[I915_TEXREG_MS3];
- state[I915_TEXREG_MS4] = t->Setup[I915_TEXREG_MS4];
-
- state[I915_TEXREG_SS2] = (i915->state.Tex[unit][I915_TEXREG_SS2] &
- SS2_LOD_BIAS_MASK);
- state[I915_TEXREG_SS2] |= (t->Setup[I915_TEXREG_SS2] & ~SS2_LOD_BIAS_MASK);
-
- state[I915_TEXREG_SS3] = (i915->state.Tex[unit][I915_TEXREG_SS3] &
- SS3_NORMALIZED_COORDS);
- state[I915_TEXREG_SS3] |= (t->Setup[I915_TEXREG_SS3] &
- ~(SS3_NORMALIZED_COORDS|
- SS3_TEXTUREMAP_INDEX_MASK));
-
- state[I915_TEXREG_SS3] |= (unit<<SS3_TEXTUREMAP_INDEX_SHIFT);
-
- state[I915_TEXREG_SS4] = t->Setup[I915_TEXREG_SS4];
-
-
- if (memcmp(state, i915->state.Tex[unit], sizeof(state)) != 0) {
- I915_STATECHANGE( i915, I915_UPLOAD_TEX(unit) );
- memcpy(i915->state.Tex[unit], state, sizeof(state));
- }
-}
-
-
-
-static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit )
-{
- i915ContextPtr i915 = I915_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *tObj = texUnit->_Current;
- i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData;
-
- if (0) fprintf(stderr, "%s %d\n", __FUNCTION__, unit);
+ memset(state, 0, sizeof(state));
- if (!(i915->state.active & I915_UPLOAD_TEX(unit))) {
- I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_TRUE);
- }
+ /* Will return the offset for the image at intelObj->firstLevel
+ * (firstLevel and lastLevel are calculated in
+ * validate_mipmap_tree). We will program the hardware as if this
+ * is level 0.
+ */
+ firstImageOffset = intel_validate_mipmap_tree( intel_context(ctx), intelObj );
+ firstImage = tObj->Image[0][intelObj->firstLevel];
- /* Fallback if there's a texture border */
- if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {
+ if (!firstImageOffset)
return GL_FALSE;
- }
-
-
- /* Update state if this is a different texture object to last
- * time.
- */
- if (i915->intel.CurrentTexObj[unit] != &t->intel ||
- (t->intel.dirty & I915_UPLOAD_TEX(unit))) {
- i915_import_tex_unit( i915, t, unit);
- i915->tex_program.translated = 0;
- }
- return GL_TRUE;
-}
+ state[I915_TEXREG_MS2] = firstImageOffset;
+ state[I915_TEXREG_MS3] =
+ (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) |
+ ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) |
+ translate_texture_format( firstImage->TexFormat->MesaFormat ) |
+ MS3_USE_FENCE_REGS);
-static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit )
-{
- i915ContextPtr i915 = I915_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *tObj = texUnit->_Current;
- i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData;
- GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3];
+ state[I915_TEXREG_MS4] =
+ ((((intelObj->mt->pitch / 4) - 1) << MS4_PITCH_SHIFT) |
+ MS4_CUBE_FACE_ENA_MASK |
+ ((((intelObj->lastLevel - intelObj->firstLevel) * 4)) << MS4_MAX_LOD_SHIFT) |
+ ((firstImage->Depth - 1) << MS4_VOLUME_DEPTH_SHIFT));
- ss3 &= ~SS3_NORMALIZED_COORDS;
- if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) {
- I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
- i915->state.Tex[unit][I915_TEXREG_SS3] = ss3;
- }
+ {
+ GLuint minFilt, mipFilt, magFilt;
- /* Upload teximages (not pipelined)
- */
- if (t->intel.base.dirty_images[0]) {
- i915SetTexImages( i915, tObj );
- if (!intelUploadTexImages( &i915->intel, &t->intel, 0 )) {
+ switch (tObj->MinFilter) {
+ case GL_NEAREST:
+ minFilt = FILTER_NEAREST;
+ mipFilt = MIPFILTER_NONE;
+ break;
+ case GL_LINEAR:
+ minFilt = FILTER_LINEAR;
+ mipFilt = MIPFILTER_NONE;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ minFilt = FILTER_NEAREST;
+ mipFilt = MIPFILTER_NEAREST;
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ minFilt = FILTER_LINEAR;
+ mipFilt = MIPFILTER_NEAREST;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ minFilt = FILTER_NEAREST;
+ mipFilt = MIPFILTER_LINEAR;
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ minFilt = FILTER_LINEAR;
+ mipFilt = MIPFILTER_LINEAR;
+ break;
+ default:
return GL_FALSE;
}
- }
- return GL_TRUE;
-}
-
-
-static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit )
-{
- i915ContextPtr i915 = I915_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *tObj = texUnit->_Current;
- i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData;
- GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3];
-
- ss3 |= SS3_NORMALIZED_COORDS;
-
- if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) {
- I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
- i915->state.Tex[unit][I915_TEXREG_SS3] = ss3;
- }
-
- /* Upload teximages (not pipelined)
- */
- if (t->intel.base.dirty_images[0]) {
- i915SetTexImages( i915, tObj );
- if (!intelUploadTexImages( &i915->intel, &t->intel, 0 )) {
- return GL_FALSE;
+ if ( tObj->MaxAnisotropy > 1.0 ) {
+ minFilt = FILTER_ANISOTROPIC;
+ magFilt = FILTER_ANISOTROPIC;
}
- }
-
- return GL_TRUE;
-}
-
-static GLboolean enable_tex_cube( GLcontext *ctx, GLuint unit )
-{
- i915ContextPtr i915 = I915_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *tObj = texUnit->_Current;
- i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData;
- GLuint ss3 = i915->state.Tex[unit][I915_TEXREG_SS3];
- GLuint face;
-
- ss3 |= SS3_NORMALIZED_COORDS;
-
- if (ss3 != i915->state.Tex[unit][I915_TEXREG_SS3]) {
- I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
- i915->state.Tex[unit][I915_TEXREG_SS3] = ss3;
- }
-
- /* Upload teximages (not pipelined)
- */
- if ( t->intel.base.dirty_images[0] || t->intel.base.dirty_images[1] ||
- t->intel.base.dirty_images[2] || t->intel.base.dirty_images[3] ||
- t->intel.base.dirty_images[4] || t->intel.base.dirty_images[5] ) {
- i915SetTexImages( i915, tObj );
- }
-
- /* upload (per face) */
- for (face = 0; face < 6; face++) {
- if (t->intel.base.dirty_images[face]) {
- if (!intelUploadTexImages( &i915->intel, &t->intel, face )) {
+ else {
+ switch (tObj->MagFilter) {
+ case GL_NEAREST:
+ magFilt = FILTER_NEAREST;
+ break;
+ case GL_LINEAR:
+ magFilt = FILTER_LINEAR;
+ break;
+ default:
return GL_FALSE;
- }
+ }
}
- }
+ state[I915_TEXREG_SS2] = i915->lodbias_ss2[unit];
- return GL_TRUE;
-}
+ /* YUV conversion:
+ */
+ if (firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR ||
+ firstImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV)
+ state[I915_TEXREG_SS2] |= SS2_COLORSPACE_CONVERSION;
-static GLboolean enable_tex_3d( GLcontext *ctx, GLuint unit )
-{
- struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
- i915TextureObjectPtr t = (i915TextureObjectPtr)tObj->DriverData;
+ /* Shadow:
+ */
+ if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB &&
+ tObj->Target != GL_TEXTURE_3D) {
- /* 3D textures on I915 seem to get bogus border colors, hence this
- * fallback:
- */
- if (t->refs_border_color)
- return GL_FALSE;
+ state[I915_TEXREG_SS2] |=
+ (SS2_SHADOW_ENABLE |
+ intel_translate_compare_func( tObj->CompareFunc ));
+
+ minFilt = FILTER_4X4_FLAT;
+ magFilt = FILTER_4X4_FLAT;
+ }
- return GL_TRUE;
-}
+ state[I915_TEXREG_SS2] |= ((minFilt << SS2_MIN_FILTER_SHIFT) |
+ (mipFilt << SS2_MIP_FILTER_SHIFT) |
+ (magFilt << SS2_MAG_FILTER_SHIFT));
+ }
+ {
+ GLenum ws = tObj->WrapS;
+ GLenum wt = tObj->WrapT;
+ GLenum wr = tObj->WrapR;
+
+ /* 3D textures don't seem to respect the border color.
+ * Fallback if there's ever a danger that they might refer to
+ * it.
+ *
+ * Effectively this means fallback on 3D clamp or
+ * clamp_to_border.
+ */
+ if (tObj->Target == GL_TEXTURE_3D &&
+ (tObj->MinFilter != GL_NEAREST ||
+ tObj->MagFilter != GL_NEAREST) &&
+ (ws == GL_CLAMP ||
+ wt == GL_CLAMP ||
+ wr == GL_CLAMP ||
+ ws == GL_CLAMP_TO_BORDER ||
+ wt == GL_CLAMP_TO_BORDER ||
+ wr == GL_CLAMP_TO_BORDER))
+ return GL_FALSE;
+
-
-static GLboolean disable_tex( GLcontext *ctx, GLuint unit )
-{
- i915ContextPtr i915 = I915_CONTEXT(ctx);
+ state[I915_TEXREG_SS3] = ss3; /* SS3_NORMALIZED_COORDS */
- if (i915->state.active & I915_UPLOAD_TEX(unit)) {
- I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(unit), GL_FALSE);
- }
+ state[I915_TEXREG_SS3] |= ((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) |
+ (translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) |
+ (translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT));
- /* The old texture is no longer bound to this texture unit.
- * Mark it as such.
- */
- if ( i915->intel.CurrentTexObj[unit] != NULL ) {
- i915->intel.CurrentTexObj[unit]->base.bound &= ~(1U << 0);
- i915->intel.CurrentTexObj[unit] = NULL;
+ state[I915_TEXREG_SS3] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT);
}
- return GL_TRUE;
-}
-static GLboolean i915UpdateTexUnit( GLcontext *ctx, GLuint unit )
-{
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ state[I915_TEXREG_SS4] = INTEL_PACKCOLOR8888(tObj->_BorderChan[0],
+ tObj->_BorderChan[1],
+ tObj->_BorderChan[2],
+ tObj->_BorderChan[3]);
+
- if (texUnit->_ReallyEnabled &&
- INTEL_CONTEXT(ctx)->intelScreen->tex.size < 2048 * 1024)
- return GL_FALSE;
- switch (texUnit->_ReallyEnabled) {
- case TEXTURE_1D_BIT:
- case TEXTURE_2D_BIT:
- return (enable_tex_2d( ctx, unit ) &&
- enable_tex_common( ctx, unit ));
- case TEXTURE_RECT_BIT:
- return (enable_tex_rect( ctx, unit ) &&
- enable_tex_common( ctx, unit ));
- case TEXTURE_CUBE_BIT:
- return (enable_tex_cube( ctx, unit ) &&
- enable_tex_common( ctx, unit ));
- case TEXTURE_3D_BIT:
- return (enable_tex_2d( ctx, unit ) &&
- enable_tex_common( ctx, unit ) &&
- enable_tex_3d( ctx, unit));
- case 0:
- return disable_tex( ctx, unit );
- default:
- return GL_FALSE;
+ if (memcmp(state, i915->state.Tex[unit], sizeof(state)) != 0) {
+ I915_STATECHANGE( i915, I915_UPLOAD_TEX(unit) );
+ memcpy(i915->state.Tex[unit], state, sizeof(state));
}
+
+ return GL_TRUE;
}
+
void i915UpdateTextureState( intelContextPtr intel )
{
GLcontext *ctx = &intel->ctx;
@@ -912,7 +282,26 @@ void i915UpdateTextureState( intelContextPtr intel )
GLuint i;
for (i = 0 ; i < I915_TEX_UNITS && ok ; i++) {
- ok = i915UpdateTexUnit( ctx, i );
+ switch (ctx->Texture.Unit[i]._ReallyEnabled) {
+ case TEXTURE_1D_BIT:
+ case TEXTURE_2D_BIT:
+ case TEXTURE_CUBE_BIT:
+ ok = i915_update_tex_unit( ctx, i, SS3_NORMALIZED_COORDS );
+ break;
+ case TEXTURE_RECT_BIT:
+ case TEXTURE_3D_BIT:
+ ok = i915_update_tex_unit( ctx, i, 0 );
+ break;
+ case 0: {
+ struct i915_context *i915 = i915_context(ctx);
+ if (i915->state.active & I915_UPLOAD_TEX(i))
+ I915_ACTIVESTATE(i915, I915_UPLOAD_TEX(i), GL_FALSE);
+ break;
+ }
+ default:
+ ok = GL_FALSE;
+ break;
+ }
}
FALLBACK( intel, I915_FALLBACK_TEXTURE, !ok );
diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c
index 7952866010..cd7b0c0ee7 100644
--- a/src/mesa/drivers/dri/i915/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i915_vtbl.c
@@ -44,7 +44,7 @@
static void i915_render_start( intelContextPtr intel )
{
GLcontext *ctx = &intel->ctx;
- i915ContextPtr i915 = I915_CONTEXT(intel);
+ i915ContextPtr i915 = i915_context(&intel->ctx);
if (ctx->FragmentProgram._Active)
i915ValidateFragmentProgram( i915 );
@@ -56,7 +56,7 @@ static void i915_render_start( intelContextPtr intel )
static void i915_reduced_primitive_state( intelContextPtr intel,
GLenum rprim )
{
- i915ContextPtr i915 = I915_CONTEXT(intel);
+ i915ContextPtr i915 = i915_context(&intel->ctx);
GLuint st1 = i915->state.Stipple[I915_STPREG_ST1];
st1 &= ~ST1_ENABLE;
@@ -88,7 +88,7 @@ static void i915_reduced_primitive_state( intelContextPtr intel,
static GLboolean i915_check_vertex_size( intelContextPtr intel,
GLuint expected )
{
- i915ContextPtr i915 = I915_CONTEXT(intel);
+ i915ContextPtr i915 = i915_context(&intel->ctx);
int lis2 = i915->current->Ctx[I915_CTXREG_LIS2];
int lis4 = i915->current->Ctx[I915_CTXREG_LIS4];
int i, sz = 0;
@@ -218,7 +218,7 @@ do { \
*/
static void i915_emit_state( intelContextPtr intel )
{
- i915ContextPtr i915 = I915_CONTEXT(intel);
+ i915ContextPtr i915 = i915_context(&intel->ctx);
struct i915_hw_state *state = i915->current;
int i;
GLuint dirty;
@@ -314,14 +314,15 @@ static void i915_destroy_context( intelContextPtr intel )
static void i915_set_draw_offset( intelContextPtr intel, int offset )
{
- i915ContextPtr i915 = I915_CONTEXT(intel);
+ i915ContextPtr i915 = i915_context(&intel->ctx);
I915_STATECHANGE( i915, I915_UPLOAD_BUFFERS );
i915->state.Buffer[I915_DESTREG_CBUFADDR2] = offset;
}
static void i915_lost_hardware( intelContextPtr intel )
{
- I915_CONTEXT(intel)->state.emitted = 0;
+ i915ContextPtr i915 = i915_context(&intel->ctx);
+ i915->state.emitted = 0;
}
static void i915_emit_flush( intelContextPtr intel )
diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c
index 170d1df25d..dad68a19ec 100644
--- a/src/mesa/drivers/dri/i915/intel_context.c
+++ b/src/mesa/drivers/dri/i915/intel_context.c
@@ -300,9 +300,6 @@ GLboolean intelInitContext( intelContextPtr intel,
intel->sarea = saPriv;
- (void) memset( intel->texture_heaps, 0, sizeof( intel->texture_heaps ) );
- make_empty_list( & intel->swapped );
-
ctx->Const.MaxTextureMaxAnisotropy = 2.0;
ctx->Const.MinLineWidth = 1.0;
@@ -438,14 +435,7 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
/* This share group is about to go away, free our private
* texture object data.
*/
- int i;
-
- for ( i = 0 ; i < intel->nr_heaps ; i++ ) {
- driDestroyTextureHeap( intel->texture_heaps[ i ] );
- intel->texture_heaps[ i ] = NULL;
- }
-
- assert( is_empty_list( & intel->swapped ) );
+ fprintf(stderr, "do somethign to free texture heaps\n");
}
/* free the Mesa context */
@@ -586,7 +576,6 @@ void intelGetLock( intelContextPtr intel, GLuint flags )
__DRIscreenPrivate *sPriv = intel->driScreen;
drmI830Sarea * sarea = intel->sarea;
int me = intel->hHWContext;
- unsigned i;
drmGetLock(intel->driFd, intel->hHWContext, flags);
@@ -609,15 +598,6 @@ void intelGetLock( intelContextPtr intel, GLuint flags )
sarea->ctxOwner = me;
}
- /* Shared texture managment - if another client has played with
- * texture space, figure out which if any of our textures have been
- * ejected, and update our global LRU.
- */
-
- for ( i = 0 ; i < intel->nr_heaps ; i++ ) {
- DRI_AGE_TEXTURES( intel->texture_heaps[ i ] );
- }
-
if (dPriv && intel->lastStamp != dPriv->lastStamp) {
intelWindowMoved( intel );
intel->lastStamp = dPriv->lastStamp;
diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h
index 20e2660dc3..d3885b25b2 100644
--- a/src/mesa/drivers/dri/i915/intel_context.h
+++ b/src/mesa/drivers/dri/i915/intel_context.h
@@ -47,8 +47,6 @@
#define DV_PF_565 (2<<8)
#define DV_PF_8888 (3<<8)
-#define INTEL_CONTEXT(ctx) ((intelContextPtr)(ctx))
-
typedef struct intel_context intelContext;
typedef struct intel_context *intelContextPtr;
typedef struct intel_texture_object *intelTextureObjectPtr;
@@ -72,30 +70,34 @@ extern void intelFallback( intelContextPtr intel, GLuint bit, GLboolean mode );
#define INTEL_TEX_MAXLEVELS 10
+
struct intel_texture_object
{
- driTextureObject base; /* the parent class */
+ struct gl_texture_object base; /* The "parent" object */
- GLuint texelBytes;
- GLuint age;
- GLuint Pitch;
- GLuint Height;
- GLuint TextureOffset;
- GLubyte *BufAddr;
+ /* The mipmap tree must include at least these levels once
+ * validated:
+ */
+ GLuint firstLevel;
+ GLuint lastLevel;
- GLuint min_level;
- GLuint max_level;
- GLuint depth_pitch;
+ /* On validation any active images held in main memory or in other
+ * regions will be copied to this region and the old storage freed.
+ */
+ struct intel_mipmap_tree *mt;
+};
- struct {
- const struct gl_texture_image *image;
- GLuint offset; /* into BufAddr */
- GLuint height;
- GLuint internalFormat;
- } image[6][INTEL_TEX_MAXLEVELS];
-
- GLuint dirty;
- GLuint firstLevel,lastLevel;
+
+
+struct intel_texture_image {
+ struct gl_texture_image base;
+
+ /* These aren't stored in gl_texture_image
+ */
+ GLuint level;
+ GLuint face;
+
+ struct intel_mipmap_tree *mt;
};
@@ -179,12 +181,9 @@ struct intel_context
GLboolean hw_stencil;
GLboolean hw_stipple;
- /* Texture object bookkeeping
+ /* AGP memory buffer manager:
*/
- GLuint nr_heaps;
- driTexHeap * texture_heaps[1];
- driTextureObject swapped;
- GLuint lastStamp;
+ struct bufmgr *bm;
struct intel_texture_object *CurrentTexObj[MAX_TEXTURE_UNITS];
@@ -212,7 +211,6 @@ struct intel_context
GLuint numClipRects; /* cliprects for that buffer */
drm_clip_rect_t *pClipRects;
- int dirtyAge;
int perf_boxes;
int do_irqs;
@@ -228,6 +226,8 @@ struct intel_context
__DRIscreenPrivate *driScreen;
intelScreenPrivate *intelScreen;
drmI830Sarea *sarea;
+
+ GLuint lastStamp;
/**
* Configuration cache
@@ -512,6 +512,25 @@ extern void intel_dump_batchbuffer( long offset,
extern void intelInitPixelFuncs( struct dd_function_table *functions );
+/* Inline conversion functions. These are better-typed than the macros used previously:
+ */
+static inline struct intel_context *intel_context( GLcontext *ctx )
+{
+ return (struct intel_context *)ctx;
+}
+
+static inline struct intel_texture_object *intel_texture_object( struct gl_texture_object *obj )
+{
+ return (struct intel_texture_object *)obj;
+}
+
+static inline struct intel_texture_image *intel_texture_image( struct gl_texture_image *img )
+{
+ return (struct intel_texture_image *)img;
+}
+
+#define INTEL_CONTEXT(ctx) intel_context(ctx)
+
#endif
diff --git a/src/mesa/drivers/dri/i915/intel_ioctl.c b/src/mesa/drivers/dri/i915/intel_ioctl.c
index e3ad40b873..ebe2f760be 100644
--- a/src/mesa/drivers/dri/i915/intel_ioctl.c
+++ b/src/mesa/drivers/dri/i915/intel_ioctl.c
@@ -91,15 +91,6 @@ void intelWaitIrq( intelContextPtr intel, int seq )
-static void age_intel( intelContextPtr intel, int age )
-{
- GLuint i;
-
- for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
- if (intel->CurrentTexObj[i])
- intel->CurrentTexObj[i]->age = age;
-}
-
void intel_dump_batchbuffer( long offset,
int *ptr,
int count )
@@ -263,8 +254,6 @@ void intelFlushBatchLocked( intelContextPtr intel,
}
- age_intel(intel, intel->sarea->last_enqueue);
-
/* FIXME: use hardware contexts to avoid 'losing' hardware after
* each buffer flush.
*/
@@ -402,6 +391,11 @@ void *intelAllocateAGP( intelContextPtr intel, GLsizei size )
drmI830MemAlloc alloc;
int ret;
+ /* This won't work with the current state of the texture memory
+ * manager:
+ */
+ assert(0);
+
if (0)
fprintf(stderr, "%s: %d bytes\n", __FUNCTION__, size);
@@ -412,11 +406,6 @@ void *intelAllocateAGP( intelContextPtr intel, GLsizei size )
LOCK_HARDWARE(intel);
- /* Make sure the global heap is initialized
- */
- if (intel->texture_heaps[0])
- driAgeTextures( intel->texture_heaps[0] );
-
ret = drmCommandWriteRead( intel->driFd,
DRM_I830_ALLOC,
@@ -431,13 +420,6 @@ void *intelAllocateAGP( intelContextPtr intel, GLsizei size )
if (0)
fprintf(stderr, "%s: allocated %d bytes\n", __FUNCTION__, size);
- /* Need to propogate this information (agp memory in use) to our
- * local texture lru. The kernel has already updated the global
- * lru. An alternative would have been to allocate memory the
- * usual way and then notify the kernel to pin the allocation.
- */
- if (intel->texture_heaps[0])
- driAgeTextures( intel->texture_heaps[0] );
UNLOCK_HARDWARE(intel);
diff --git a/src/mesa/drivers/dri/i915/intel_pixel.c b/src/mesa/drivers/dri/i915/intel_pixel.c
index a79bed45fb..2c47b2f5d0 100644
--- a/src/mesa/drivers/dri/i915/intel_pixel.c
+++ b/src/mesa/drivers/dri/i915/intel_pixel.c
@@ -39,7 +39,7 @@
static GLboolean
-check_color( const GLcontext *ctx, GLenum type, GLenum format,
+check_color( GLcontext *ctx, GLenum type, GLenum format,
const struct gl_pixelstore_attrib *packing,
const void *pixels, GLint sz, GLint pitch )
{
@@ -96,7 +96,7 @@ check_color_per_fragment_ops( const GLcontext *ctx )
static GLboolean
-clip_pixelrect( const GLcontext *ctx,
+clip_pixelrect( GLcontext *ctx,
const GLframebuffer *buffer,
GLint *x, GLint *y,
GLsizei *width, GLsizei *height,
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c
index c4a2e53b3d..7896f02b94 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -338,12 +338,16 @@ static GLboolean intelCreateContext( const __GLcontextModes *mesaVis,
intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
switch (intelScreen->deviceID) {
+#if 0
+ /* Don't deal with i830 until texture work complete:
+ */
case PCI_CHIP_845_G:
case PCI_CHIP_I830_M:
case PCI_CHIP_I855_GM:
case PCI_CHIP_I865_G:
return i830CreateContext( mesaVis, driContextPriv,
sharedContextPrivate );
+#endif
case PCI_CHIP_I915_G:
case PCI_CHIP_I915_GM:
diff --git a/src/mesa/drivers/dri/i915/intel_tex.c b/src/mesa/drivers/dri/i915/intel_tex.c
index d256dbf7cb..d1a12f7275 100644
--- a/src/mesa/drivers/dri/i915/intel_tex.c
+++ b/src/mesa/drivers/dri/i915/intel_tex.c
@@ -1,830 +1,75 @@
-/**************************************************************************
- *
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#include "glheader.h"
-#include "mtypes.h"
-#include "imports.h"
-#include "macros.h"
-#include "simple_list.h"
-#include "enums.h"
-#include "image.h"
-#include "texstore.h"
-#include "texformat.h"
-#include "teximage.h"
-#include "texmem.h"
#include "texobj.h"
-#include "swrast/swrast.h"
-
-#include "mm.h"
-
-#include "intel_screen.h"
-#include "intel_batchbuffer.h"
#include "intel_context.h"
+#include "intel_mipmap_tree.h"
#include "intel_tex.h"
-#include "intel_ioctl.h"
-
-
-
-static GLboolean
-intelValidateClientStorage( intelContextPtr intel, GLenum target,
- GLint internalFormat,
- GLint srcWidth, GLint srcHeight,
- GLenum format, GLenum type, const void *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
-
-{
- GLcontext *ctx = &intel->ctx;
- int texelBytes;
-
- if (0)
- fprintf(stderr, "intformat %s format %s type %s\n",
- _mesa_lookup_enum_by_nr( internalFormat ),
- _mesa_lookup_enum_by_nr( format ),
- _mesa_lookup_enum_by_nr( type ));
-
- if (!ctx->Unpack.ClientStorage)
- return 0;
-
- if (ctx->_ImageTransferState ||
- texImage->IsCompressed ||
- texObj->GenerateMipmap)
- return 0;
-
-
- /* This list is incomplete
- */
- switch ( internalFormat ) {
- case GL_RGBA:
- if ( format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
- texImage->TexFormat = &_mesa_texformat_argb8888;
- texelBytes = 4;
- }
- else
- return 0;
- break;
-
- case GL_RGB:
- if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
- texImage->TexFormat = &_mesa_texformat_rgb565;
- texelBytes = 2;
- }
- else
- return 0;
- break;
-
- case GL_YCBCR_MESA:
- if ( format == GL_YCBCR_MESA &&
- type == GL_UNSIGNED_SHORT_8_8_REV_APPLE ) {
- texImage->TexFormat = &_mesa_texformat_ycbcr_rev;
- texelBytes = 2;
- }
- else if ( format == GL_YCBCR_MESA &&
- (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
- type == GL_UNSIGNED_BYTE)) {
- texImage->TexFormat = &_mesa_texformat_ycbcr;
- texelBytes = 2;
- }
- else
- return 0;
- break;
-
-
- default:
- return 0;
- }
-
- /* Could deal with these packing issues, but currently don't:
- */
- if (packing->SkipPixels ||
- packing->SkipRows ||
- packing->SwapBytes ||
- packing->LsbFirst) {
- return 0;
- }
-
- {
- GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth,
- format, type);
-
-
- if (0)
- fprintf(stderr, "%s: srcRowStride %d/%x\n",
- __FUNCTION__, srcRowStride, srcRowStride);
-
- /* Could check this later in upload, pitch restrictions could be
- * relaxed, but would need to store the image pitch somewhere,
- * as packing details might change before image is uploaded:
- */
- if (!intelIsAgpMemory( intel, pixels, srcHeight * srcRowStride ) ||
- (srcRowStride & 63))
- return 0;
-
-
- /* Have validated that _mesa_transfer_teximage would be a straight
- * memcpy at this point. NOTE: future calls to TexSubImage will
- * overwrite the client data. This is explicitly mentioned in the
- * extension spec.
- */
- texImage->Data = (void *)pixels;
- texImage->IsClientData = GL_TRUE;
- texImage->RowStride = srcRowStride / texelBytes;
- return 1;
- }
-}
-
-
-
-static void intelTexImage1D( GLcontext *ctx, GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint border,
- GLenum format, GLenum type, const GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
-{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
-
- assert(t);
- intelFlush( ctx );
- driSwapOutTextureObject( t );
-
- texImage->IsClientData = GL_FALSE;
-
- _mesa_store_teximage1d( ctx, target, level, internalFormat,
- width, border, format, type,
- pixels, packing, texObj, texImage );
-
- t->dirty_images[0] |= (1 << level);
-}
-
-static void intelTexSubImage1D( GLcontext *ctx,
- GLenum target,
- GLint level,
- GLint xoffset,
- GLsizei width,
- GLenum format, GLenum type,
- const GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
-{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
-
- assert(t);
- intelFlush( ctx );
- driSwapOutTextureObject( t );
-
- _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
- format, type, pixels, packing, texObj,
- texImage);
-}
-
-/* Handles 2D, CUBE, RECT:
- */
-static void intelTexImage2D( GLcontext *ctx, GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint border,
- GLenum format, GLenum type, const GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
-{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
- GLuint face;
-
- /* which cube face or ordinary 2D image */
- switch (target) {
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
- ASSERT(face < 6);
- break;
- default:
- face = 0;
- }
-
- assert(t);
- intelFlush( ctx );
- driSwapOutTextureObject( t );
- texImage->IsClientData = GL_FALSE;
-
- if (intelValidateClientStorage( INTEL_CONTEXT(ctx), target,
- internalFormat,
- width, height,
- format, type, pixels,
- packing, texObj, texImage)) {
- if (INTEL_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "%s: Using client storage\n", __FUNCTION__);
- }
- else {
- _mesa_store_teximage2d( ctx, target, level, internalFormat,
- width, height, border, format, type,
- pixels, packing, texObj, texImage );
-
- t->dirty_images[face] |= (1 << level);
- }
-}
-
-static void intelTexSubImage2D( GLcontext *ctx,
- GLenum target,
- GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
-{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
- GLuint face;
-
- /* which cube face or ordinary 2D image */
- switch (target) {
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
- ASSERT(face < 6);
- break;
- default:
- face = 0;
- }
-
- if (texImage->IsClientData &&
- (char *)pixels == (char *)texImage->Data +
- ((xoffset + yoffset * texImage->RowStride) *
- texImage->TexFormat->TexelBytes)) {
-
- /* Notification only - no upload required */
- }
- else {
- assert( t ); /* this _should_ be true */
- intelFlush( ctx );
- driSwapOutTextureObject( t );
-
- _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
- height, format, type, pixels, packing, texObj,
- texImage);
-
- t->dirty_images[face] |= (1 << level);
- }
-}
-static void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint border,
- GLsizei imageSize, const GLvoid *data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
+static GLboolean intelIsTextureResident(GLcontext *ctx,
+ struct gl_texture_object *texObj)
{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
- GLuint face;
-
- /* which cube face or ordinary 2D image */
- switch (target) {
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
- ASSERT(face < 6);
- break;
- default:
- face = 0;
- }
-
- assert(t);
- intelFlush( ctx );
-
- driSwapOutTextureObject( t );
- texImage->IsClientData = GL_FALSE;
-
- if (INTEL_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__);
+#if 0
+ struct intel_context *intel = intel_context(ctx);
+ struct intel_texture_object *intelObj = intel_texture_object(texObj);
- _mesa_store_compressed_teximage2d(ctx, target, level, internalFormat, width,
- height, border, imageSize, data, texObj, texImage);
-
- t->dirty_images[face] |= (1 << level);
+ return
+ intelObj->mt &&
+ intelObj->mt->region &&
+ intel_is_region_resident(intel, intelObj->mt->region);
+#endif
+ return 1;
}
-static void intelCompressedTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format,
- GLsizei imageSize, const GLvoid *data,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
-{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
- GLuint face;
-
-
- /* which cube face or ordinary 2D image */
- switch (target) {
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
- ASSERT(face < 6);
- break;
- default:
- face = 0;
- }
- assert( t ); /* this _should_ be true */
- intelFlush( ctx );
- driSwapOutTextureObject( t );
-
- _mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
- height, format, imageSize, data, texObj, texImage);
-
- t->dirty_images[face] |= (1 << level);
-}
-
-
-static void intelTexImage3D( GLcontext *ctx, GLenum target, GLint level,
- GLint internalFormat,
- GLint width, GLint height, GLint depth,
- GLint border,
- GLenum format, GLenum type, const GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
+static struct gl_texture_image *intelNewTextureImage( GLcontext *ctx )
{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
-
- assert(t);
- driSwapOutTextureObject( t );
- texImage->IsClientData = GL_FALSE;
-
- _mesa_store_teximage3d(ctx, target, level, internalFormat,
- width, height, depth, border,
- format, type, pixels,
- &ctx->Unpack, texObj, texImage);
-
- t->dirty_images[0] |= (1 << level);
+ (void) ctx;
+ return (struct gl_texture_image *)CALLOC_STRUCT(intel_texture_image);
}
-static void
-intelTexSubImage3D( GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type,
- const GLvoid *pixels,
- const struct gl_pixelstore_attrib *packing,
- struct gl_texture_object *texObj,
- struct gl_texture_image *texImage )
+static struct gl_texture_object *intelNewTextureObject( GLcontext *ctx,
+ GLuint name,
+ GLenum target )
{
- driTextureObject * t = (driTextureObject *) texObj->DriverData;
-
- assert( t ); /* this _should_ be true */
- driSwapOutTextureObject( t );
+ struct intel_texture_object *obj = CALLOC_STRUCT(intel_texture_object);
- _mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset,
- width, height, depth,
- format, type, pixels, packing, texObj, texImage);
+ _mesa_initialize_texture_object(&obj->base, name, target);
- t->dirty_images[0] |= (1 << level);
+ return &obj->base;
}
-
-
-static void intelDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
+static void intelFreeTextureImageData( GLcontext *ctx,
+ struct gl_texture_image *texImage )
{
- driTextureObject * t = (driTextureObject *) tObj->DriverData;
+ struct intel_context *intel = intel_context(ctx);
+ struct intel_texture_image *intelImage = intel_texture_image(texImage);
- if ( t != NULL ) {
- intelFlush( ctx );
- driDestroyTextureObject( t );
+ if (intelImage->mt) {
+ intel_miptree_release(intel, intelImage->mt);
+ intelImage->mt = NULL;
}
- /* Free mipmap images and the texture object itself */
- _mesa_delete_texture_object(ctx, tObj);
-}
-
-
-static const struct gl_texture_format *
-intelChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
- GLenum format, GLenum type )
-{
- intelContextPtr intel = INTEL_CONTEXT( ctx );
- const GLboolean do32bpt = ( intel->intelScreen->cpp == 4 &&
- intel->intelScreen->tex.size > 4*1024*1024);
-
- switch ( internalFormat ) {
- case 4:
- case GL_RGBA:
- case GL_COMPRESSED_RGBA:
- if ( format == GL_BGRA ) {
- if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
- return &_mesa_texformat_argb8888;
- }
- else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
- return &_mesa_texformat_argb4444;
- }
- else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
- return &_mesa_texformat_argb1555;
- }
- }
- return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
-
- case 3:
- case GL_RGB:
- case GL_COMPRESSED_RGB:
- if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
- return &_mesa_texformat_rgb565;
- }
- return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
-
- case GL_RGBA8:
- case GL_RGB10_A2:
- case GL_RGBA12:
- case GL_RGBA16:
- return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
-
- case GL_RGBA4:
- case GL_RGBA2:
- return &_mesa_texformat_argb4444;
-
- case GL_RGB5_A1:
- return &_mesa_texformat_argb1555;
-
- case GL_RGB8:
- case GL_RGB10:
- case GL_RGB12:
- case GL_RGB16:
- return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
-
- case GL_RGB5:
- case GL_RGB4:
- case GL_R3_G3_B2:
- return &_mesa_texformat_rgb565;
-
- case GL_ALPHA:
- case GL_ALPHA4:
- case GL_ALPHA8:
- case GL_ALPHA12:
- case GL_ALPHA16:
- case GL_COMPRESSED_ALPHA:
- return &_mesa_texformat_a8;
-
- case 1:
- case GL_LUMINANCE:
- case GL_LUMINANCE4:
- case GL_LUMINANCE8:
- case GL_LUMINANCE12:
- case GL_LUMINANCE16:
- case GL_COMPRESSED_LUMINANCE:
- return &_mesa_texformat_l8;
-
- case 2:
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE4_ALPHA4:
- case GL_LUMINANCE6_ALPHA2:
- case GL_LUMINANCE8_ALPHA8:
- case GL_LUMINANCE12_ALPHA4:
- case GL_LUMINANCE12_ALPHA12:
- case GL_LUMINANCE16_ALPHA16:
- case GL_COMPRESSED_LUMINANCE_ALPHA:
- return &_mesa_texformat_al88;
-
- case GL_INTENSITY:
- case GL_INTENSITY4:
- case GL_INTENSITY8:
- case GL_INTENSITY12:
- case GL_INTENSITY16:
- case GL_COMPRESSED_INTENSITY:
- return &_mesa_texformat_i8;
-
- case GL_YCBCR_MESA:
- if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
- type == GL_UNSIGNED_BYTE)
- return &_mesa_texformat_ycbcr;
- else
- return &_mesa_texformat_ycbcr_rev;
-
- case GL_COMPRESSED_RGB_FXT1_3DFX:
- return &_mesa_texformat_rgb_fxt1;
- case GL_COMPRESSED_RGBA_FXT1_3DFX:
- return &_mesa_texformat_rgba_fxt1;
-
- case GL_RGB_S3TC:
- case GL_RGB4_S3TC:
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
- return &_mesa_texformat_rgb_dxt1;
-
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- return &_mesa_texformat_rgba_dxt1;
-
- case GL_RGBA_S3TC:
- case GL_RGBA4_S3TC:
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
- return &_mesa_texformat_rgba_dxt3;
-
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- return &_mesa_texformat_rgba_dxt5;
-
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH_COMPONENT32:
- return &_mesa_texformat_depth_component16;
-
- default:
- fprintf(stderr, "unexpected texture format %s in %s\n",
- _mesa_lookup_enum_by_nr(internalFormat),
- __FUNCTION__);
- return NULL;
+ if (texImage->Data) {
+ free(texImage->Data);
+ texImage->Data = NULL;
}
-
- return NULL; /* never get here */
-}
-
-
-
-void intelDestroyTexObj(intelContextPtr intel, intelTextureObjectPtr t)
-{
- unsigned i;
-
- if ( intel == NULL )
- return;
-
- if ( t->age > intel->dirtyAge )
- intel->dirtyAge = t->age;
-
- for ( i = 0 ; i < MAX_TEXTURE_UNITS ; i++ ) {
- if ( t == intel->CurrentTexObj[ i ] )
- intel->CurrentTexObj[ i ] = NULL;
- }
-}
-
-
-
-/* Upload an image from mesa's internal copy. Image may be 1D, 2D or
- * 3D. Cubemaps are expanded elsewhere.
- */
-static void intelUploadTexImage( intelContextPtr intel,
- intelTextureObjectPtr t,
- const struct gl_texture_image *image,
- const GLuint offset )
-{
-
- if (!image || !image->Data)
- return;
-
- if (image->Depth == 1 && image->IsClientData) {
- if (INTEL_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "Blit uploading\n");
-
- /* Do it with a blit.
- */
- intelEmitCopyBlitLocked( intel,
- image->TexFormat->TexelBytes,
- image->RowStride, /* ? */
- intelGetMemoryOffsetMESA( NULL, 0, image->Data ),
- t->Pitch / image->TexFormat->TexelBytes,
- intelGetMemoryOffsetMESA( NULL, 0, t->BufAddr + offset ),
- 0, 0,
- 0, 0,
- image->Width,
- image->Height);
- }
- else if (image->IsCompressed) {
- GLuint row_len = image->Width * 2;
- GLubyte *dst = (GLubyte *)(t->BufAddr + offset);
- GLubyte *src = (GLubyte *)image->Data;
- GLuint j;
-
- if (INTEL_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr,
- "Upload image %dx%dx%d offset %xm row_len %x "
- "pitch %x depth_pitch %x\n",
- image->Width, image->Height, image->Depth, offset,
- row_len, t->Pitch, t->depth_pitch);
-
- switch (image->InternalFormat) {
- case GL_COMPRESSED_RGB_FXT1_3DFX:
- case GL_COMPRESSED_RGBA_FXT1_3DFX:
- case GL_RGB_S3TC:
- case GL_RGB4_S3TC:
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) {
- __memcpy(dst, src, row_len );
- src += row_len;
- }
- break;
- case GL_RGBA_S3TC:
- case GL_RGBA4_S3TC:
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) {
- __memcpy(dst, src, (image->Width*4) );
- src += image->Width*4;
- }
- break;
- default:
- fprintf(stderr,"Internal Compressed format not supported %d\n", image->InternalFormat);
- break;
- }
- }
- else {
- GLuint row_len = image->Width * image->TexFormat->TexelBytes;
- GLubyte *dst = (GLubyte *)(t->BufAddr + offset);
- GLubyte *src = (GLubyte *)image->Data;
- GLuint d, j;
-
- if (INTEL_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr,
- "Upload image %dx%dx%d offset %xm row_len %x "
- "pitch %x depth_pitch %x\n",
- image->Width, image->Height, image->Depth, offset,
- row_len, t->Pitch, t->depth_pitch);
-
- if (row_len == t->Pitch) {
- for (d = 0; d < image->Depth; d++) {
- memcpy( dst, src, t->Pitch * image->Height );
- dst += t->depth_pitch;
- src += row_len * image->Height;
- }
- }
- else {
- for (d = 0 ; d < image->Depth ; d++) {
- for (j = 0 ; j < image->Height ; j++) {
- __memcpy(dst, src, row_len );
- src += row_len;
- dst += t->Pitch;
- }
-
- dst += t->depth_pitch - (t->Pitch * image->Height);
- }
- }
- }
-}
-
-
-
-int intelUploadTexImages( intelContextPtr intel,
- intelTextureObjectPtr t,
- GLuint face)
-{
- const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;
- const struct gl_texture_image *firstImage = t->image[face][t->base.firstLevel].image;
- int pitch = firstImage->RowStride * firstImage->TexFormat->TexelBytes;
-
- /* Can we texture out of the existing client data? */
- if ( numLevels == 1 &&
- firstImage->IsClientData &&
- (pitch & 3) == 0) {
-
- if (INTEL_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "AGP texturing from client memory\n");
-
- t->TextureOffset = intelAgpOffsetFromVirtual( intel, firstImage->Data );
- t->BufAddr = 0;
- t->dirty = ~0;
- return GL_TRUE;
- }
- else {
- if (INTEL_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "Uploading client data to agp\n");
-
- INTEL_FIREVERTICES( intel );
- LOCK_HARDWARE( intel );
-
- if ( t->base.memBlock == NULL ) {
- int heap;
-
- heap = driAllocateTexture( intel->texture_heaps, intel->nr_heaps,
- (driTextureObject *) t );
- if ( heap == -1 ) {
- UNLOCK_HARDWARE( intel );
- return GL_FALSE;
- }
-
- /* Set the base offset of the texture image */
- t->BufAddr = intel->intelScreen->tex.map + t->base.memBlock->ofs;
- t->TextureOffset = intel->intelScreen->tex.offset + t->base.memBlock->ofs;
- t->dirty = ~0;
- }
-
-
- /* Let the world know we've used this memory recently.
- */
- driUpdateTextureLRU( (driTextureObject *) t );
-
-
- /* Upload any images that are new */
- if (t->base.dirty_images[face]) {
- int i;
-
- intelWaitForIdle( intel );
-
- for (i = 0 ; i < numLevels ; i++) {
- int level = i + t->base.firstLevel;
-
- if (t->base.dirty_images[face] & (1<<level)) {
-
- const struct gl_texture_image *image = t->image[face][i].image;
- GLuint offset = t->image[face][i].offset;
-
- if (INTEL_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "upload level %d, offset %x\n",
- level, offset);
-
- intelUploadTexImage( intel, t, image, offset );
- }
- }
- t->base.dirty_images[face] = 0;
- intel->perf_boxes |= I830_BOX_TEXTURE_LOAD;
- }
-
- UNLOCK_HARDWARE( intel );
- return GL_TRUE;
- }
-}
-
-/**
- * Allocate a new texture object.
- * Called via ctx->Driver.NewTextureObject.
- * Note: this function will be called during context creation to
- * allocate the default texture objects.
- * Note: we could use containment here to 'derive' the driver-specific
- * texture object from the core mesa gl_texture_object. Not done at this time.
- */
-static struct gl_texture_object *
-intelNewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
-{
- struct gl_texture_object *obj = _mesa_new_texture_object(ctx, name, target);
- INTEL_CONTEXT(ctx)->vtbl.alloc_tex_obj( obj );
- return obj;
}
-void intelInitTextureFuncs( struct dd_function_table *functions )
+void intelInitTextureFuncs(struct dd_function_table * functions)
{
- functions->NewTextureObject = intelNewTextureObject;
- functions->ChooseTextureFormat = intelChooseTextureFormat;
- functions->TexImage1D = intelTexImage1D;
- functions->TexImage2D = intelTexImage2D;
- functions->TexImage3D = intelTexImage3D;
- functions->TexSubImage1D = intelTexSubImage1D;
- functions->TexSubImage2D = intelTexSubImage2D;
- functions->TexSubImage3D = intelTexSubImage3D;
- functions->CopyTexImage1D = _swrast_copy_teximage1d;
- functions->CopyTexImage2D = _swrast_copy_teximage2d;
- functions->CopyTexSubImage1D = _swrast_copy_texsubimage1d;
- functions->CopyTexSubImage2D = _swrast_copy_texsubimage2d;
- functions->CopyTexSubImage3D = _swrast_copy_texsubimage3d;
- functions->DeleteTexture = intelDeleteTexture;
- functions->UpdateTexturePalette = NULL;
- functions->IsTextureResident = driIsTextureResident;
- functions->TestProxyTexImage = _mesa_test_proxy_teximage;
- functions->DeleteTexture = intelDeleteTexture;
- functions->CompressedTexImage2D = intelCompressedTexImage2D;
- functions->CompressedTexSubImage2D = intelCompressedTexSubImage2D;
+ functions->ChooseTextureFormat = intelChooseTextureFormat;
+ functions->TexImage1D = intelTexImage1D;
+ functions->TexImage2D = intelTexImage2D;
+ functions->TexSubImage1D = intelTexSubImage1D;
+ functions->TexSubImage2D = intelTexSubImage2D;
+ functions->NewTextureObject = intelNewTextureObject;
+ functions->NewTextureImage = intelNewTextureImage;
+ functions->DeleteTexture = _mesa_delete_texture_object;
+ functions->FreeTexImageData = intelFreeTextureImageData;
+ functions->TextureMemCpy = _mesa_memcpy;
+ functions->UpdateTexturePalette = 0;
+ functions->IsTextureResident = intelIsTextureResident;
}
diff --git a/src/mesa/drivers/dri/i915/intel_tex.h b/src/mesa/drivers/dri/i915/intel_tex.h
index 0a1f697e9d..9ce775270f 100644
--- a/src/mesa/drivers/dri/i915/intel_tex.h
+++ b/src/mesa/drivers/dri/i915/intel_tex.h
@@ -35,8 +35,54 @@
void intelInitTextureFuncs( struct dd_function_table *functions );
-void intelDestroyTexObj( intelContextPtr intel, intelTextureObjectPtr t );
-int intelUploadTexImages( intelContextPtr intel, intelTextureObjectPtr t,
- GLuint face );
+const struct gl_texture_format *
+intelChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
+ GLenum format, GLenum type );
+
+void intelTexImage2D(GLcontext *ctx,
+ GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+void intelTexSubImage2D(GLcontext *ctx,
+ GLenum target,
+ GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+void intelTexImage1D(GLcontext *ctx,
+ GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint border,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+void intelTexSubImage1D(GLcontext *ctx,
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage);
+
+GLuint intel_validate_mipmap_tree( struct intel_context *intel,
+ struct intel_texture_object *intelObj );
+
+
+
#endif
diff --git a/src/mesa/drivers/dri/i915/intel_tex_format.c b/src/mesa/drivers/dri/i915/intel_tex_format.c
new file mode 100644
index 0000000000..30da841987
--- /dev/null
+++ b/src/mesa/drivers/dri/i915/intel_tex_format.c
@@ -0,0 +1,145 @@
+#include "intel_context.h"
+#include "intel_tex.h"
+#include "texformat.h"
+#include "enums.h"
+
+/* It works out that this function is fine for all the supported
+ * hardware. However, there is still a need to map the formats onto
+ * hardware descriptors.
+ */
+const struct gl_texture_format *
+intelChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
+ GLenum format, GLenum type )
+{
+ intelContextPtr intel = INTEL_CONTEXT( ctx );
+ const GLboolean do32bpt = ( intel->intelScreen->cpp == 4 &&
+ intel->intelScreen->tex.size > 4*1024*1024);
+
+ switch ( internalFormat ) {
+ case 4:
+ case GL_RGBA:
+ case GL_COMPRESSED_RGBA:
+ if ( format == GL_BGRA ) {
+ if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
+ return &_mesa_texformat_argb8888;
+ }
+ else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
+ return &_mesa_texformat_argb4444;
+ }
+ else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
+ return &_mesa_texformat_argb1555;
+ }
+ }
+ return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
+
+ case 3:
+ case GL_RGB:
+ case GL_COMPRESSED_RGB:
+ if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
+ return &_mesa_texformat_rgb565;
+ }
+ return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
+
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
+
+ case GL_RGBA4:
+ case GL_RGBA2:
+ return &_mesa_texformat_argb4444;
+
+ case GL_RGB5_A1:
+ return &_mesa_texformat_argb1555;
+
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
+
+ case GL_RGB5:
+ case GL_RGB4:
+ case GL_R3_G3_B2:
+ return &_mesa_texformat_rgb565;
+
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ case GL_COMPRESSED_ALPHA:
+ return &_mesa_texformat_a8;
+
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ case GL_COMPRESSED_LUMINANCE:
+ return &_mesa_texformat_l8;
+
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ case GL_COMPRESSED_LUMINANCE_ALPHA:
+ return &_mesa_texformat_al88;
+
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ case GL_COMPRESSED_INTENSITY:
+ return &_mesa_texformat_i8;
+
+ case GL_YCBCR_MESA:
+ if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
+ type == GL_UNSIGNED_BYTE)
+ return &_mesa_texformat_ycbcr;
+ else
+ return &_mesa_texformat_ycbcr_rev;
+
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ return &_mesa_texformat_rgb_fxt1;
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+ return &_mesa_texformat_rgba_fxt1;
+
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ return &_mesa_texformat_rgb_dxt1;
+
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ return &_mesa_texformat_rgba_dxt1;
+
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ return &_mesa_texformat_rgba_dxt3;
+
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ return &_mesa_texformat_rgba_dxt5;
+
+ case GL_DEPTH_COMPONENT:
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT24:
+ case GL_DEPTH_COMPONENT32:
+ return &_mesa_texformat_depth_component16;
+
+ default:
+ fprintf(stderr, "unexpected texture format %s in %s\n",
+ _mesa_lookup_enum_by_nr(internalFormat),
+ __FUNCTION__);
+ return NULL;
+ }
+
+ return NULL; /* never get here */
+}
diff --git a/src/mesa/drivers/dri/i915/intel_tex_image.c b/src/mesa/drivers/dri/i915/intel_tex_image.c
new file mode 100644
index 0000000000..0cb553c554
--- /dev/null
+++ b/src/mesa/drivers/dri/i915/intel_tex_image.c
@@ -0,0 +1,315 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "glheader.h"
+#include "macros.h"
+#include "mtypes.h"
+#include "enums.h"
+#include "colortab.h"
+#include "convolve.h"
+#include "context.h"
+#include "simple_list.h"
+#include "texcompress.h"
+#include "texformat.h"
+#include "texobj.h"
+#include "texstore.h"
+
+#include "intel_context.h"
+#include "intel_mipmap_tree.h"
+#include "intel_tex.h"
+#include "intel_ioctl.h"
+
+
+/* Functions to store texture images. Where possible, mipmap_tree's
+ * will be created or further instantiated with image data, otherwise
+ * images will be stored in malloc'd memory. A validation step is
+ * required to pull those images into a mipmap tree, or otherwise
+ * decide a fallback is required.
+ */
+
+
+static int logbase2(int n)
+{
+ GLint i = 1;
+ GLint log2 = 0;
+
+ while (n > i) {
+ i *= 2;
+ log2++;
+ }
+
+ return log2;
+}
+
+
+/* Otherwise, store it in memory if (Border != 0) or (any dimension ==
+ * 1).
+ *
+ * Otherwise, if max_level >= level >= min_level, create tree with
+ * space for textures from min_level down to max_level.
+ *
+ * Otherwise, create tree with space for textures from (level
+ * 0)..(1x1). Consider pruning this tree at a validation if the
+ * saving is worth it.
+ */
+static void guess_and_alloc_mipmap_tree( struct intel_context *intel,
+ struct intel_texture_object *intelObj,
+ struct intel_texture_image *intelImage )
+{
+ GLuint firstLevel;
+ GLuint lastLevel;
+ GLuint width = intelImage->base.Width;
+ GLuint height = intelImage->base.Height;
+ GLuint depth = intelImage->base.Depth;
+ GLuint l2width, l2height, l2depth;
+ GLuint i;
+
+ if (intelImage->base.Border)
+ return;
+
+ if (intelImage->level > intelObj->base.BaseLevel &&
+ (intelImage->base.Width == 1 ||
+ (intelObj->base.Target != GL_TEXTURE_1D &&
+ intelImage->base.Height == 1) ||
+ (intelObj->base.Target == GL_TEXTURE_3D &&
+ intelImage->base.Depth == 1)))
+ return;
+
+ /* If this image disrespects BaseLevel, allocate from level zero.
+ * Usually BaseLevel == 0, so it's unlikely to happen.
+ */
+ if (intelImage->level < intelObj->base.BaseLevel)
+ firstLevel = 0;
+ else
+ firstLevel = intelObj->base.BaseLevel;
+
+
+ /* Figure out image dimensions at start level.
+ */
+ for (i = intelImage->level; i > firstLevel; i--) {
+ width <<= 1;
+ if (height != 1) height <<= 1;
+ if (depth != 1) depth <<= 1;
+ }
+
+ /* Guess a reasonable value for lastLevel. This is probably going
+ * to be wrong fairly often and might mean that we have to look at
+ * resizable buffers, or require that buffers implement lazy
+ * pagetable arrangements.
+ */
+ if ((intelObj->base.MinFilter == GL_NEAREST ||
+ intelObj->base.MinFilter == GL_LINEAR) &&
+ intelImage->level == firstLevel) {
+ lastLevel = firstLevel;
+ }
+ else {
+ l2width = logbase2(width);
+ l2height = logbase2(height);
+ l2depth = logbase2(depth);
+ lastLevel = firstLevel + MAX2(MAX2(l2width,l2height),l2depth);
+ }
+
+
+ intelObj->mt = intel_miptree_create( intel,
+ intelObj->base.Target,
+ intelImage->base.InternalFormat,
+ firstLevel,
+ lastLevel,
+ width,
+ height,
+ depth,
+ intelImage->base.TexFormat->TexelBytes,
+ intelImage->base.IsCompressed );
+}
+
+
+
+
+static GLuint target_to_face( GLenum target )
+{
+ switch (target) {
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
+ return ((GLuint) target -
+ (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
+ default:
+ return 0;
+ }
+}
+
+
+static void intelTexImage(GLcontext *ctx,
+ GLint dims,
+ GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ struct intel_context *intel = intel_context(ctx);
+ struct intel_texture_object *intelObj = intel_texture_object(texObj);
+ struct intel_texture_image *intelImage = intel_texture_image(texImage);
+ GLint postConvWidth = width;
+ GLint postConvHeight = height;
+ GLint texelBytes, sizeInBytes;
+ GLuint dstRowStride;
+
+ intelImage->face = target_to_face( target );
+ intelImage->level = level;
+
+ if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
+ _mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
+ &postConvHeight);
+ }
+
+ /* choose the texture format */
+ texImage->TexFormat = intelChooseTextureFormat(ctx, internalFormat,
+ format, type);
+
+ assert(texImage->TexFormat);
+
+ if (dims == 1) {
+ texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
+ texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
+ }
+ else {
+ texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
+ texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
+ }
+ texelBytes = texImage->TexFormat->TexelBytes;
+
+
+ /* Minimum pitch of 32 bytes */
+ if (postConvWidth * texelBytes < 32) {
+ postConvWidth = 32 / texelBytes;
+ texImage->RowStride = postConvWidth;
+ }
+
+ assert(texImage->RowStride == postConvWidth);
+
+ /* Release the reference to a potentially orphaned buffer.
+ * Release any old malloced memory.
+ */
+ if (intelImage->mt) {
+ intel_miptree_release(intel, intelImage->mt);
+ intelImage->mt = NULL;
+ assert(!texImage->Data);
+ }
+ else if (texImage->Data) {
+ free(texImage->Data);
+ }
+
+ pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
+ format, type,
+ pixels, packing, "glTexImage");
+ if (!pixels)
+ return;
+
+ if (!intelObj->mt) {
+ guess_and_alloc_mipmap_tree(intel, intelObj, intelImage);
+ }
+
+ LOCK_HARDWARE(intel);
+
+ if (intelObj->mt &&
+ intel_miptree_match_image(intelObj->mt, &intelImage->base,
+ intelImage->face, intelImage->level)) {
+
+ texImage->Data = intel_miptree_image_map(intel,
+ intelObj->mt,
+ intelImage->face,
+ intelImage->level,
+ &dstRowStride);
+ }
+ else {
+ /* Allocate regular memory and store the image there temporarily. */
+ if (texImage->IsCompressed) {
+ sizeInBytes = texImage->CompressedSize;
+ dstRowStride = _mesa_compressed_row_stride(texImage->InternalFormat,width);
+ }
+ else {
+ sizeInBytes = postConvWidth * postConvHeight * texelBytes;
+ dstRowStride = postConvWidth * texImage->TexFormat->TexelBytes;
+ }
+
+ texImage->Data = malloc(sizeInBytes);
+ }
+
+ /* Copy data. Would like to know when it's ok for us to eg. use
+ * the blitter to copy. Or, use the hardware to do the format
+ * conversion and copy:
+ */
+ if (!texImage->TexFormat->StoreImage(ctx, dims,
+ texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride, 0 /* dstImageStride */,
+ width, height, 1,
+ format, type, pixels, packing)) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
+ }
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+
+ if (intelImage->mt) {
+ intel_miptree_image_unmap(intel, intelImage->mt);
+ texImage->Data = NULL;
+ }
+
+ UNLOCK_HARDWARE(intel);
+
+#if 0
+ /* GL_SGIS_generate_mipmap -- this can be accelerated now.
+ */
+ if (level == texObj->BaseLevel &&
+ texObj->GenerateMipmap) {
+ intel_generate_mipmap(ctx, target,
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+ texObj);
+ }
+#endif
+}
+
+
+void intelTexImage2D(GLcontext *ctx,
+ GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ intelTexImage( ctx, 2, target, level,
+ internalFormat, width, height, border,
+ format, type, pixels,
+ packing, texObj, texImage );
+}
+
+void intelTexImage1D(GLcontext *ctx,
+ GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint border,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ intelTexImage( ctx, 1, target, level,
+ internalFormat, width, 1, border,
+ format, type, pixels,
+ packing, texObj, texImage );
+}
+
+
+
+
+
diff --git a/src/mesa/drivers/dri/i915/intel_tex_subimage.c b/src/mesa/drivers/dri/i915/intel_tex_subimage.c
new file mode 100644
index 0000000000..5c5e4a2b31
--- /dev/null
+++ b/src/mesa/drivers/dri/i915/intel_tex_subimage.c
@@ -0,0 +1,115 @@
+
+
+#include "mtypes.h"
+#include "texobj.h"
+#include "texstore.h"
+
+#include "intel_context.h"
+#include "intel_tex.h"
+#include "intel_mipmap_tree.h"
+
+
+static void intelTexSubimage (GLcontext *ctx,
+ GLint dims,
+ GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint width, GLint height,
+ GLenum format, GLenum type, const void *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ struct intel_context *intel = intel_context(ctx);
+ struct intel_texture_image *intelImage = intel_texture_image(texImage);
+ GLuint dstImageStride = 0;
+ GLuint dstRowStride;
+
+ pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, format, type,
+ pixels, packing, "glTexSubImage2D");
+ if (!pixels)
+ return;
+
+ LOCK_HARDWARE(intel);
+
+ /* Map buffer if necessary. Need to lock to prevent other contexts
+ * from uploading the buffer under us.
+ */
+ if (intelImage->mt)
+ texImage->Data = intel_miptree_image_map(intel,
+ intelImage->mt,
+ intelImage->face,
+ intelImage->level,
+ &dstRowStride );
+
+
+ if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ xoffset, yoffset, 0,
+ dstRowStride, dstImageStride,
+ width, height, 1,
+ format, type, pixels, packing)) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
+ }
+
+#if 0
+ /* GL_SGIS_generate_mipmap */
+ if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
+ _mesa_generate_mipmap(ctx, target,
+ &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
+ texObj);
+ }
+#endif
+
+ _mesa_unmap_teximage_pbo(ctx, packing);
+
+ if (intelImage->mt) {
+ intel_miptree_image_unmap(intel, intelImage->mt);
+ texImage->Data = NULL;
+ }
+
+ UNLOCK_HARDWARE(intel);
+}
+
+
+
+
+
+
+void intelTexSubImage2D(GLcontext *ctx,
+ GLenum target,
+ GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+
+ intelTexSubimage(ctx, 2,
+ target, level, xoffset, yoffset, width,
+ height, format, type, pixels, packing, texObj,
+ texImage);
+
+}
+
+
+void intelTexSubImage1D(GLcontext *ctx,
+ GLenum target,
+ GLint level,
+ GLint xoffset,
+ GLsizei width,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+ intelTexSubimage(ctx, 1,
+ target, level, xoffset, 0, width,
+ 1, format, type, pixels, packing, texObj,
+ texImage);
+
+}
diff --git a/src/mesa/drivers/dri/i915/intel_tex_validate.c b/src/mesa/drivers/dri/i915/intel_tex_validate.c
new file mode 100644
index 0000000000..e99f91cc77
--- /dev/null
+++ b/src/mesa/drivers/dri/i915/intel_tex_validate.c
@@ -0,0 +1,198 @@
+#include "mtypes.h"
+#include "macros.h"
+
+#include "intel_context.h"
+#include "intel_mipmap_tree.h"
+#include "intel_tex.h"
+
+
+/**
+ * Compute which mipmap levels that really need to be sent to the hardware.
+ * This depends on the base image size, GL_TEXTURE_MIN_LOD,
+ * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
+ */
+static void intel_calculate_first_last_level( struct intel_texture_object *intelObj )
+{
+ struct gl_texture_object *tObj = &intelObj->base;
+ const struct gl_texture_image * const baseImage =
+ tObj->Image[0][tObj->BaseLevel];
+
+ /* These must be signed values. MinLod and MaxLod can be negative numbers,
+ * and having firstLevel and lastLevel as signed prevents the need for
+ * extra sign checks.
+ */
+ int firstLevel;
+ int lastLevel;
+
+ /* Yes, this looks overly complicated, but it's all needed.
+ */
+ switch (tObj->Target) {
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_CUBE_MAP:
+ if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
+ /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
+ */
+ firstLevel = lastLevel = tObj->BaseLevel;
+ }
+ else {
+ firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5);
+ firstLevel = MAX2(firstLevel, tObj->BaseLevel);
+ lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5);
+ lastLevel = MAX2(lastLevel, tObj->BaseLevel);
+ lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
+ lastLevel = MIN2(lastLevel, tObj->MaxLevel);
+ lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
+ }
+ break;
+ case GL_TEXTURE_RECTANGLE_NV:
+ case GL_TEXTURE_4D_SGIS:
+ firstLevel = lastLevel = 0;
+ break;
+ default:
+ return;
+ }
+
+ /* save these values */
+ intelObj->firstLevel = firstLevel;
+ intelObj->lastLevel = lastLevel;
+}
+
+static void copy_image_data_to_tree( struct intel_context *intel,
+ struct intel_mipmap_tree *mt,
+ struct intel_texture_image *intelImage )
+{
+ if (intelImage->mt) {
+ /* Copy potentially with the blitter:
+ */
+ intel_miptree_image_copy(intel,
+ mt,
+ intelImage->face,
+ intelImage->level,
+ intelImage->mt);
+
+ intel_miptree_release(intel, intelImage->mt);
+ }
+ else {
+ assert(intelImage->base.Data != NULL);
+
+ /* More straightforward upload.
+ */
+ intel_miptree_image_data(intel,
+ mt,
+ intelImage->face,
+ intelImage->level,
+ intelImage->base.Data,
+ intelImage->base.RowStride);
+
+ free(intelImage->base.Data);
+ intelImage->base.Data = NULL;
+ }
+
+ intelImage->mt = intel_miptree_reference(mt);
+}
+
+
+/*
+ */
+GLuint intel_validate_mipmap_tree( struct intel_context *intel,
+ struct intel_texture_object *intelObj )
+{
+ GLuint face, i;
+ GLuint nr_faces = 0;
+ struct intel_texture_image *firstImage;
+
+ /* We know/require this is true by now:
+ */
+ assert(intelObj->base.Complete);
+
+ /* What levels must the tree include at a minimum?
+ */
+ intel_calculate_first_last_level( intelObj );
+ firstImage = intel_texture_image(intelObj->base.Image[0][intelObj->firstLevel]);
+
+ /* Fallback case:
+ */
+ if (firstImage->base.Border) {
+ if (intelObj->mt) {
+ intel_miptree_release(intel, intelObj->mt);
+ intelObj->mt = NULL;
+ }
+ return 0;
+ }
+
+
+ /* If both firstImage and intelObj have a tree which can contain
+ * all active images, favour firstImage.
+ */
+ if (firstImage->mt &&
+ firstImage->mt != intelObj->mt &&
+ firstImage->mt->first_level <= intelObj->firstLevel &&
+ firstImage->mt->last_level >= intelObj->lastLevel) {
+
+ if (intelObj->mt)
+ intel_miptree_release(intel, intelObj->mt);
+
+ intelObj->mt = intel_miptree_reference(firstImage->mt);
+ }
+
+ /* Check tree can hold all active levels. Check tree matches
+ * target, imageFormat, etc.
+ */
+ if (intelObj->mt &&
+ ((intelObj->mt->first_level > intelObj->firstLevel) ||
+ (intelObj->mt->last_level < intelObj->lastLevel) ||
+ (intelObj->mt->internal_format != firstImage->base.InternalFormat))) {
+ intel_miptree_release(intel, intelObj->mt);
+ intelObj->mt = NULL;
+ }
+
+
+ /* May need to create a new tree:
+ */
+ if (!intelObj->mt) {
+ assert(!firstImage->mt);
+ intelObj->mt = intel_miptree_create(intel,
+ intelObj->base.Target,
+ firstImage->base.InternalFormat,
+ intelObj->firstLevel,
+ intelObj->lastLevel,
+ firstImage->base.Width,
+ firstImage->base.Height,
+ firstImage->base.Depth,
+ firstImage->base.TexFormat->TexelBytes,
+ firstImage->base.IsCompressed);
+ }
+
+ assert(intelObj->mt);
+
+ assert(firstImage->mt == intelObj->mt ||
+ firstImage->mt == NULL);
+
+ nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
+
+ for (face = 0; face < nr_faces; face++) {
+ for (i = intelObj->firstLevel; i < intelObj->lastLevel; i++) {
+ struct intel_texture_image *intelImage =
+ intel_texture_image(intelObj->base.Image[face][i]);
+
+ /* Need to import images in main memory or held in other trees.
+ */
+ if (intelObj->mt != intelImage->mt) {
+ copy_image_data_to_tree(intel,
+ intelObj->mt,
+ intelImage);
+ }
+ }
+ }
+
+ return GL_TRUE;
+}
+
+
+
+
+
+
+