From c59270e2b82abe9bcb0af6a1593b81772f6306d3 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Sun, 19 Sep 2004 08:03:46 +0000 Subject: Add GL_ARB_texture_cube_map support for i830. Most of the code was lifted from the i915 side. i830 will now report version 1.3! Hurrah! With the exception of GL_EXT_texture_compression_s3tc, the i830 driver now supports all the extensions that its Windows counterpart supports. --- src/mesa/drivers/dri/i915/i830_context.c | 2 +- src/mesa/drivers/dri/i915/i830_context.h | 5 +- src/mesa/drivers/dri/i915/i830_reg.h | 1 + src/mesa/drivers/dri/i915/i830_texstate.c | 177 +++++++++++++++++++++++------- src/mesa/drivers/dri/i915/i830_vtbl.c | 6 +- src/mesa/drivers/dri/i915/i915_context.c | 1 - src/mesa/drivers/dri/i915/intel_context.c | 3 +- 7 files changed, 149 insertions(+), 46 deletions(-) (limited to 'src/mesa/drivers/dri/i915') diff --git a/src/mesa/drivers/dri/i915/i830_context.c b/src/mesa/drivers/dri/i915/i830_context.c index 2c81e3de6d..fc63386cbe 100644 --- a/src/mesa/drivers/dri/i915/i830_context.c +++ b/src/mesa/drivers/dri/i915/i830_context.c @@ -99,7 +99,7 @@ GLboolean i830CreateContext( const __GLcontextModes *mesaVis, 4, 11, /* max 2D texture size is 2048x2048 */ 8, /* max 3D texture size is 256^3 */ - 0, /* max CUBE. not supported */ + 10, /* max CUBE texture size is 1024x1024 */ 11, /* max RECT. supported */ 12, GL_FALSE ); diff --git a/src/mesa/drivers/dri/i915/i830_context.h b/src/mesa/drivers/dri/i915/i830_context.h index 48eb704cea..62e20d0a02 100644 --- a/src/mesa/drivers/dri/i915/i830_context.h +++ b/src/mesa/drivers/dri/i915/i830_context.h @@ -89,8 +89,9 @@ #define I830_TEXREG_TM0S2 3 #define I830_TEXREG_TM0S3 4 #define I830_TEXREG_TM0S4 5 -#define I830_TEXREG_MCS 6 /* _3DSTATE_MAP_COORD_SETS */ -#define I830_TEX_SETUP_SIZE 7 +#define I830_TEXREG_MCS 6 /* _3DSTATE_MAP_COORD_SETS */ +#define I830_TEXREG_CUBE 7 /* _3DSTATE_MAP_SUBE */ +#define I830_TEX_SETUP_SIZE 8 #define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */ diff --git a/src/mesa/drivers/dri/i915/i830_reg.h b/src/mesa/drivers/dri/i915/i830_reg.h index 69dc333d2c..b931a6b63c 100644 --- a/src/mesa/drivers/dri/i915/i830_reg.h +++ b/src/mesa/drivers/dri/i915/i830_reg.h @@ -637,6 +637,7 @@ #define TM0S2_PITCH_SHIFT 21 #define TM0S2_CUBE_FACE_ENA_SHIFT 15 +#define TM0S2_CUBE_FACE_ENA_MASK (1<<15) #define TM0S2_MAP_FORMAT (1<<14) #define TM0S2_VERTICAL_LINE_STRIDE (1<<13) #define TM0S2_VERITCAL_LINE_STRIDE_OFF (1<<12) diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c index 39ba0b8ec3..a393fd1d52 100644 --- a/src/mesa/drivers/dri/i915/i830_texstate.c +++ b/src/mesa/drivers/dri/i915/i830_texstate.c @@ -42,6 +42,19 @@ #include "i830_context.h" #include "i830_reg.h" +static const GLint initial_offsets[6][2] = { {0,0}, + {0,2}, + {1,0}, + {1,2}, + {1,1}, + {1,3} }; + +static const GLint step_offsets[6][2] = { {0,2}, + {0,2}, + {-1,2}, + {-1,2}, + {-1,1}, + {-1,1} }; #define I830_TEX_UNIT_ENABLED(unit) (1<intel.base.lastLevel; numLevels = lastLevel - firstLevel + 1; - /* Pitch would be subject to additional rules if texture memory were - * tiled. Currently it isn't. - */ - if (0) { - pitch = 128; - while (pitch < tObj->Image[0][firstLevel]->Width * t->intel.texelBytes) - pitch *= 2; - } - else { - pitch = tObj->Image[0][firstLevel]->Width * t->intel.texelBytes; - pitch = (pitch + 3) & ~3; - } - /* All images must be loaded at this pitch. Count the number of * lines required: */ - 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; + 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; - t->intel.image[0][i].offset = total_height * pitch; - t->intel.image[0][i].internalFormat = baseImage->Format; - 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); + 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->Format; + + d >>= 1; + x += step_offsets[face][0] * d; + y += step_offsets[face][1] * d; + } + } + 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->Format; + 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; @@ -176,7 +222,8 @@ static GLboolean i830SetTexImages( i830ContextPtr i830, ((tObj->Image[0][firstLevel]->Width - 1) << TM0S1_WIDTH_SHIFT) | textureFormat); t->Setup[I830_TEXREG_TM0S2] = - (((pitch / 4) - 1) << TM0S2_PITCH_SHIFT); + (((pitch / 4) - 1) << TM0S2_PITCH_SHIFT) | + TM0S2_CUBE_FACE_ENA_MASK; 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; @@ -216,6 +263,7 @@ static void i830_import_tex_unit( i830ContextPtr i830, i830->state.Tex[unit][I830_TEXREG_TM0S4] = t->Setup[I830_TEXREG_TM0S4]; i830->state.Tex[unit][I830_TEXREG_MCS] = (t->Setup[I830_TEXREG_MCS] & ~MAP_UNIT_MASK); + 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); @@ -267,9 +315,11 @@ static GLboolean enable_tex_rect( GLcontext *ctx, GLuint unit ) mcs &= ~TEXCOORDS_ARE_NORMAL; mcs |= TEXCOORDS_ARE_IN_TEXELUNITS; - if (mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) { + if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) + || (0 != i830->state.Tex[unit][I830_TEXREG_CUBE])) { I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); i830->state.Tex[unit][I830_TEXREG_MCS] = mcs; + i830->state.Tex[unit][I830_TEXREG_CUBE] = 0; } return GL_TRUE; @@ -284,15 +334,61 @@ static GLboolean enable_tex_2d( GLcontext *ctx, GLuint unit ) mcs &= ~TEXCOORDS_ARE_IN_TEXELUNITS; mcs |= TEXCOORDS_ARE_NORMAL; - if (mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) { + if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) + || (0 != i830->state.Tex[unit][I830_TEXREG_CUBE])) { I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); i830->state.Tex[unit][I830_TEXREG_MCS] = mcs; + i830->state.Tex[unit][I830_TEXREG_CUBE] = 0; } return GL_TRUE; } +static GLboolean enable_tex_cube( GLcontext *ctx, GLuint unit ) +{ + i830ContextPtr i830 = I830_CONTEXT(ctx); + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + struct gl_texture_object *tObj = texUnit->_Current; + i830TextureObjectPtr t = (i830TextureObjectPtr)tObj->DriverData; + GLuint mcs = i830->state.Tex[unit][I830_TEXREG_MCS]; + const GLuint cube = CUBE_NEGX_ENABLE | CUBE_POSX_ENABLE + | CUBE_NEGY_ENABLE | CUBE_POSY_ENABLE + | CUBE_NEGZ_ENABLE | CUBE_POSZ_ENABLE; + GLuint face; + + mcs &= ~TEXCOORDS_ARE_IN_TEXELUNITS; + mcs |= TEXCOORDS_ARE_NORMAL; + + if ((mcs != i830->state.Tex[unit][I830_TEXREG_MCS]) + || (cube != i830->state.Tex[unit][I830_TEXREG_CUBE])) { + I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit)); + i830->state.Tex[unit][I830_TEXREG_MCS] = mcs; + i830->state.Tex[unit][I830_TEXREG_CUBE] = cube; + } + + /* 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] ) { + i830SetTexImages( i830, tObj ); + } + + /* upload (per face) */ + for (face = 0; face < 6; face++) { + if (t->intel.base.dirty_images[face]) { + if (!intelUploadTexImages( &i830->intel, &t->intel, face )) { + return GL_FALSE; + } + } + } + + + return GL_TRUE; +} + + static GLboolean disable_tex( GLcontext *ctx, GLuint unit ) { i830ContextPtr i830 = I830_CONTEXT(ctx); @@ -324,20 +420,21 @@ static GLboolean i830UpdateTexUnit( GLcontext *ctx, GLuint unit ) INTEL_CONTEXT(ctx)->intelScreen->textureSize < 2048 * 1024) return GL_FALSE; - if (texUnit->_ReallyEnabled == TEXTURE_1D_BIT || - texUnit->_ReallyEnabled == TEXTURE_2D_BIT) { + switch(texUnit->_ReallyEnabled) { + case TEXTURE_1D_BIT: + case TEXTURE_2D_BIT: return (enable_tex_common( ctx, unit ) && enable_tex_2d( ctx, unit )); - } - else if (texUnit->_ReallyEnabled == TEXTURE_RECT_BIT) { + case TEXTURE_RECT_BIT: return (enable_tex_common( ctx, unit ) && enable_tex_rect( ctx, unit )); - } - else if (texUnit->_ReallyEnabled) { - return GL_FALSE; - } - else { + case TEXTURE_CUBE_BIT: + return (enable_tex_common( ctx, unit ) && + enable_tex_cube( ctx, unit )); + case 0: return disable_tex( ctx, unit ); + default: + return GL_FALSE; } } diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c index b0a7287c90..22939e8e5c 100644 --- a/src/mesa/drivers/dri/i915/i830_vtbl.c +++ b/src/mesa/drivers/dri/i915/i830_vtbl.c @@ -121,11 +121,15 @@ static void i830_render_start( intelContextPtr intel ) switch (sz) { case 1: case 2: - case 3: /* XXX: fix for CUBE/VOLUME textures */ emit = EMIT_2F; sz = 2; mcs |= TEXCOORDTYPE_CARTESIAN; break; + case 3: + emit = EMIT_3F; + sz = 3; + mcs |= TEXCOORDTYPE_VECTOR; + break; case 4: emit = EMIT_3F_XYW; sz = 3; diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c index 4cfc502d89..ff2ac28b8d 100644 --- a/src/mesa/drivers/dri/i915/i915_context.c +++ b/src/mesa/drivers/dri/i915/i915_context.c @@ -48,7 +48,6 @@ static const char * const card_extensions[] = { "GL_ARB_fragment_program", - "GL_ARB_texture_cube_map", NULL }; diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index 610e0f5423..e637d38a11 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -72,7 +72,7 @@ int prevLockLine; * Mesa's Driver Functions ***************************************/ -#define DRIVER_DATE "20040914" +#define DRIVER_DATE "20040919" const GLubyte *intelGetString( GLcontext *ctx, GLenum name ) { @@ -144,6 +144,7 @@ static const char * const card_extensions[] = "GL_ARB_multitexture", "GL_ARB_point_parameters", "GL_ARB_texture_border_clamp", + "GL_ARB_texture_cube_map", "GL_ARB_texture_compression", "GL_ARB_texture_env_add", "GL_ARB_texture_env_combine", -- cgit v1.2.3