summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/mga/mgatex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/drivers/dri/mga/mgatex.c')
-rw-r--r--src/mesa/drivers/dri/mga/mgatex.c904
1 files changed, 235 insertions, 669 deletions
diff --git a/src/mesa/drivers/dri/mga/mgatex.c b/src/mesa/drivers/dri/mga/mgatex.c
index b4ee787e0b8..82eccc81498 100644
--- a/src/mesa/drivers/dri/mga/mgatex.c
+++ b/src/mesa/drivers/dri/mga/mgatex.c
@@ -26,10 +26,7 @@
*/
/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.c,v 1.14 2002/10/30 12:51:36 alanh Exp $ */
-#include <stdlib.h>
-#include <stdio.h>
-#include <GL/gl.h>
-
+#include "glheader.h"
#include "mm.h"
#include "mgacontext.h"
#include "mgatex.h"
@@ -37,9 +34,11 @@
#include "mgatris.h"
#include "mgaioctl.h"
+#include "colormac.h"
+#include "context.h"
#include "enums.h"
#include "simple_list.h"
-/*#include "mem.h"*/
+#include "imports.h"
#include "macros.h"
#include "texformat.h"
#include "texstore.h"
@@ -47,67 +46,72 @@
#include "swrast/swrast.h"
-#define TEX_0 1
-#define TEX_1 2
-
-/*
- * mgaDestroyTexObj
- * Free all memory associated with a texture and NULL any pointers
- * to it.
+/**
+ * Set the texture wrap modes.
+ * Currently \c GL_REPEAT, \c GL_CLAMP and \c GL_CLAMP_TO_EDGE are supported.
+ *
+ * \param t Texture object whose wrap modes are to be set
+ * \param swrap Wrap mode for the \a s texture coordinate
+ * \param twrap Wrap mode for the \a t texture coordinate
*/
-void
-mgaDestroyTexObj( mgaContextPtr mmesa, mgaTextureObjectPtr t )
+
+static void
+mgaSetTexWrapping( mgaTextureObjectPtr t, GLenum swrap, GLenum twrap )
{
- if ( !t ) return;
+ GLboolean is_clamp = GL_FALSE;
+ GLboolean is_clamp_to_edge = GL_FALSE;
- /* free the texture memory */
- if (t->MemBlock) {
- mmFreeMem( t->MemBlock );
- t->MemBlock = 0;
+ t->setup.texctl &= (TMC_clampu_MASK & TMC_clampv_MASK);
+ t->setup.texctl2 &= (TMC_borderen_MASK);
- if (mmesa && t->age > mmesa->dirtyAge)
- mmesa->dirtyAge = t->age;
+ switch( swrap ) {
+ case GL_REPEAT:
+ break;
+ case GL_CLAMP:
+ t->setup.texctl |= TMC_clampu_enable;
+ is_clamp = GL_TRUE;
+ break;
+ case GL_CLAMP_TO_EDGE:
+ t->setup.texctl |= TMC_clampu_enable;
+ is_clamp_to_edge = GL_TRUE;
+ break;
+ default:
+ _mesa_problem(NULL, "bad S wrap mode in %s", __FUNCTION__);
}
- /* free mesa's link */
- if (t->tObj)
- t->tObj->DriverData = NULL;
-
- /* see if it was the driver's current object */
- if (mmesa) {
- if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0;
- if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0;
+ switch( twrap ) {
+ case GL_REPEAT:
+ break;
+ case GL_CLAMP:
+ t->setup.texctl |= TMC_clampv_enable;
+ is_clamp = GL_TRUE;
+ break;
+ case GL_CLAMP_TO_EDGE:
+ t->setup.texctl |= TMC_clampv_enable;
+ is_clamp_to_edge = GL_TRUE;
+ break;
+ default:
+ _mesa_problem(NULL, "bad T wrap mode in %s", __FUNCTION__);
}
-
- remove_from_list(t);
- free( t );
-}
+ if ( is_clamp ) {
+ t->setup.texctl2 |= TMC_borderen_enable;
+ }
-/*
- * mgaSetTexWrappings
- */
-static void mgaSetTexWrapping( mgaTextureObjectPtr t,
- GLenum sWrap,
- GLenum tWrap )
-{
- GLuint val = 0;
-
- if (sWrap != GL_REPEAT)
- val |= TMC_clampu_enable;
-
- if (tWrap != GL_REPEAT)
- val |= TMC_clampv_enable;
-
- t->setup.texctl &= ~(TMC_clampu_enable|TMC_clampv_enable);
- t->setup.texctl |= val;
+ t->border_fallback = (is_clamp && is_clamp_to_edge);
}
-/*
- * mgaSetTexFilter
+/**
+ * Set the texture magnification and minification modes.
+ *
+ * \param t Texture whose filter modes are to be set
+ * \param minf Texture minification mode
+ * \param magf Texture magnification mode
*/
-static void mgaSetTexFilter(mgaTextureObjectPtr t, GLenum minf, GLenum magf)
+
+static void
+mgaSetTexFilter( mgaTextureObjectPtr t, GLenum minf, GLenum magf )
{
GLuint val = 0;
@@ -136,123 +140,79 @@ static void mgaSetTexFilter(mgaTextureObjectPtr t, GLenum minf, GLenum magf)
}
- t->setup.texfilter &= (TF_minfilter_MASK |
- TF_magfilter_MASK |
+ /* Mask off the bits for the fields we are setting. Remember, the MGA mask
+ * defines have 0s for the bits in the named fields. This is the opposite
+ * of most of the other drivers.
+ */
+
+ t->setup.texfilter &= (TF_minfilter_MASK &
+ TF_magfilter_MASK &
TF_fthres_MASK);
t->setup.texfilter |= val;
}
-/*
- * mgaSetTexBorderColor
- */
static void mgaSetTexBorderColor(mgaTextureObjectPtr t, GLubyte color[4])
{
- t->setup.texbordercol = MGAPACKCOLOR8888(color[0],color[1],
- color[2],color[3]);
+ t->setup.texbordercol = PACK_COLOR_8888(color[3], color[0],
+ color[1], color[2] );
}
-static GLint mgaChooseTexFormat( mgaContextPtr mmesa,
- struct gl_texture_image *texImage,
- GLenum format, GLenum type )
+static const struct gl_texture_format *
+mgaChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
+ GLenum format, GLenum type )
{
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
const GLboolean do32bpt = mmesa->default32BitTextures;
- const struct gl_texture_format *texFormat;
- GLint ret;
-
- if ( 0 )
- fprintf( stderr, "internal=%s format=%s type=%s\n",
- texImage->IntFormat == 3 ? "GL_RGB (3)" :
- texImage->IntFormat == 4 ? "GL_RGBA (4)" :
- _mesa_lookup_enum_by_nr( texImage->IntFormat ),
- _mesa_lookup_enum_by_nr( format ),
- _mesa_lookup_enum_by_nr( type ) );
-
-#define SET_FORMAT( r, gl ) \
- do { \
- ret = (r); \
- texFormat = &(gl); \
- } while (0)
-
-#define SET_FORMAT_32BPT( r32, gl32, r16, gl16 ) \
- do { \
- if ( do32bpt ) { \
- ret = (r32); \
- texFormat = &(gl32); \
- } else { \
- ret = (r16); \
- texFormat = &(gl16); \
- } \
- } while (0)
-
- switch ( texImage->IntFormat ) {
- /* GH: Bias towards GL_RGB, GL_RGBA texture formats. This has
- * got to be better than sticking them way down the end of this
- * huge list.
- */
+
+ 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 ) {
- SET_FORMAT( TMC_tformat_tw32, _mesa_texformat_argb8888 );
- break;
- } else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
- SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
- break;
- } else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
- SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 );
- break;
+ 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;
}
}
- SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
- TMC_tformat_tw12, _mesa_texformat_argb4444 );
- break;
+ 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 ) {
- SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 );
- break;
+ return &_mesa_texformat_rgb565;
}
- SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
- TMC_tformat_tw16, _mesa_texformat_rgb565 );
- break;
+ return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
- /* GH: Okay, keep checking as normal. Still test for GL_RGB,
- * GL_RGBA formats first.
- */
case GL_RGBA8:
case GL_RGB10_A2:
case GL_RGBA12:
case GL_RGBA16:
- SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
- TMC_tformat_tw12, _mesa_texformat_argb4444 );
- break;
+ return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
case GL_RGBA4:
case GL_RGBA2:
- SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
- break;
+ return &_mesa_texformat_argb4444;
case GL_RGB5_A1:
- SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 );
- break;
+ return &_mesa_texformat_argb1555;
case GL_RGB8:
case GL_RGB10:
case GL_RGB12:
case GL_RGB16:
- SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888,
- TMC_tformat_tw16, _mesa_texformat_rgb565 );
- break;
+ return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
case GL_RGB5:
case GL_RGB4:
case GL_R3_G3_B2:
- SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 );
- break;
+ return &_mesa_texformat_rgb565;
case GL_ALPHA:
case GL_ALPHA4:
@@ -261,8 +221,7 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa,
case GL_ALPHA16:
case GL_COMPRESSED_ALPHA:
/* FIXME: This will report incorrect component sizes... */
- SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
- break;
+ return &_mesa_texformat_argb4444;
case 1:
case GL_LUMINANCE:
@@ -272,8 +231,7 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa,
case GL_LUMINANCE16:
case GL_COMPRESSED_LUMINANCE:
/* FIXME: This will report incorrect component sizes... */
- SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 );
- break;
+ return &_mesa_texformat_rgb565;
case 2:
case GL_LUMINANCE_ALPHA:
@@ -285,8 +243,7 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa,
case GL_LUMINANCE16_ALPHA16:
case GL_COMPRESSED_LUMINANCE_ALPHA:
/* FIXME: This will report incorrect component sizes... */
- SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
- break;
+ return &_mesa_texformat_argb4444;
case GL_INTENSITY:
case GL_INTENSITY4:
@@ -295,8 +252,15 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa,
case GL_INTENSITY16:
case GL_COMPRESSED_INTENSITY:
/* FIXME: This will report incorrect component sizes... */
- SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 );
- break;
+ return &_mesa_texformat_argb4444;
+
+ case GL_YCBCR_MESA:
+ if (MGA_IS_G400(mmesa) &&
+ (type == GL_UNSIGNED_SHORT_8_8_APPLE ||
+ type == GL_UNSIGNED_BYTE))
+ return &_mesa_texformat_ycbcr;
+ else
+ return &_mesa_texformat_ycbcr_rev;
case GL_COLOR_INDEX:
case GL_COLOR_INDEX1_EXT:
@@ -305,502 +269,78 @@ static GLint mgaChooseTexFormat( mgaContextPtr mmesa,
case GL_COLOR_INDEX8_EXT:
case GL_COLOR_INDEX12_EXT:
case GL_COLOR_INDEX16_EXT:
- SET_FORMAT( TMC_tformat_tw8, _mesa_texformat_ci8 );
- break;
+ return &_mesa_texformat_ci8;
default:
- fprintf( stderr, "bad texture format in mgaChooseTexFormat() %d",
- texImage->IntFormat );
- return -1;
+ _mesa_problem( ctx, "unexpected texture format in %s", __FUNCTION__ );
+ return NULL;
}
- texImage->TexFormat = texFormat;
-
- return ret;
+ return NULL; /* never get here */
}
-/*
- * mgaCreateTexObj
+
+
+/**
* 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.
*/
-static void mgaCreateTexObj(mgaContextPtr mmesa,
- struct gl_texture_object *tObj)
-{
- const GLint baseLevel = tObj->BaseLevel;
- struct gl_texture_image *image = tObj->Image[baseLevel];
- mgaTextureObjectPtr t;
- int i, ofs;
- int LastLevel;
- int s, s2;
- int tformat;
-
- if (!image) return;
-
- tObj->DriverData = t = calloc( 1, sizeof( *t ) );
- if (!t) {
- fprintf(stderr, "mgaCreateTexObj: Failed to malloc mgaTextureObject\n" );
- return;
- }
-
- /* FIXME: Use the real DD interface...
- */
- tformat = mgaChooseTexFormat( mmesa, image, image->Format,
- GL_UNSIGNED_BYTE );
- t->texelBytes = image->TexFormat->TexelBytes;
-
- /* We are going to upload all levels that are present, even if
- * later levels wouldn't be used by the current filtering mode. This
- * allows the filtering mode to change without forcing another upload
- * of the images.
- */
- LastLevel = MGA_TEX_MAXLEVELS-1;
-
- ofs = 0;
- for ( i = 0 ; i <= LastLevel ; i++ ) {
- if ( !tObj->Image[i] ) {
- LastLevel = i - 1;
- break;
- }
-
- t->offsets[i] = ofs;
- t->dirty_images |= (1<<i);
-
- ofs += ((MAX2( tObj->Image[i]->Width, 8 ) *
- MAX2( tObj->Image[i]->Height, 8 ) *
- t->texelBytes) + 31) & ~31;
- }
- t->totalSize = ofs;
- t->lastLevel = LastLevel;
- t->tObj = tObj;
- t->ctx = mmesa;
- t->age = 0;
- t->bound = 0;
- t->MemBlock = 0;
-
- insert_at_tail(&(mmesa->SwappedOut), t);
-
-
- /* setup hardware register values */
- t->setup.texctl = TMC_takey_1 | TMC_tamask_0 | tformat;
-
- if (image->WidthLog2 >= 3)
- t->setup.texctl |= ((image->WidthLog2 - 3) << TMC_tpitch_SHIFT);
- else
- t->setup.texctl |= (TMC_tpitchlin_enable |
- (image->Width << TMC_tpitchext_SHIFT));
-
-
- t->setup.texctl2 = TMC_ckstransdis_enable;
-
- if ( mmesa->glCtx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR )
- t->setup.texctl2 |= TMC_specen_enable;
-
-
- t->setup.texfilter = (TF_minfilter_nrst |
- TF_magfilter_nrst |
- TF_filteralpha_enable |
- (0x10 << TF_fthres_SHIFT) |
- (LastLevel << TF_mapnb_SHIFT));
-
- /* warp texture registers */
- ofs = MGA_IS_G200(mmesa) ? 28 : 11;
- s = image->Width;
- s2 = image->WidthLog2;
- t->setup.texwidth = (MGA_FIELD(TW_twmask, s - 1) |
- MGA_FIELD(TW_rfw, (10 - s2 - 8) & 63 ) |
- MGA_FIELD(TW_tw, (s2 + ofs ) | 0x40 ));
-
- s = image->Height;
- s2 = image->HeightLog2;
- t->setup.texheight = (MGA_FIELD(TH_thmask, s - 1) |
- MGA_FIELD(TH_rfh, (10 - s2 - 8) & 63 ) |
- MGA_FIELD(TH_th, (s2 + ofs ) | 0x40 ));
-
-
- /* set all the register values for filtering, border, etc */
- mgaSetTexWrapping( t, tObj->WrapS, tObj->WrapT );
- mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
- mgaSetTexBorderColor( t, tObj->_BorderChan );
-}
-
-
-
-
-static void mgaUpdateTextureEnvG200( GLcontext *ctx )
+static mgaTextureObjectPtr
+mgaAllocTexObj( struct gl_texture_object *tObj )
{
- struct gl_texture_object *tObj = ctx->Texture.Unit[0]._Current;
mgaTextureObjectPtr t;
- if (!tObj || !tObj->DriverData)
- return;
-
- t = (mgaTextureObjectPtr)tObj->DriverData;
-
- t->setup.texctl2 &= ~TMC_decalblend_enable;
-
- switch (ctx->Texture.Unit[0].EnvMode) {
- case GL_REPLACE:
- t->setup.texctl &= ~TMC_tmodulate_enable;
- break;
- case GL_MODULATE:
- t->setup.texctl |= TMC_tmodulate_enable;
- break;
- case GL_DECAL:
- t->setup.texctl &= ~TMC_tmodulate_enable;
- t->setup.texctl2 |= TMC_decalblend_enable;
- break;
- case GL_BLEND:
- FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
- break;
- default:
- break;
- }
-}
-
-static void mgaUpdateTextureEnvG400( GLcontext *ctx, int unit )
-{
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit);
- GLuint source = mmesa->tmu_source[unit];
- struct gl_texture_object *tObj = ctx->Texture.Unit[source]._Current;
- GLenum format;
-
- if ( tObj != ctx->Texture.Unit[source].Current2D || !tObj )
- return;
-
- format = tObj->Image[tObj->BaseLevel]->Format;
-
- switch (ctx->Texture.Unit[source].EnvMode) {
- case GL_REPLACE:
- if (format == GL_RGB || format == GL_LUMINANCE) {
- *reg = (TD0_color_sel_arg1 |
- TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_arg2 );
- }
- else if (format == GL_ALPHA) {
- *reg = (TD0_color_sel_arg2 |
- TD0_color_arg2_diffuse |
- TD0_alpha_sel_arg1 );
- }
- else {
- *reg = (TD0_color_sel_arg1 |
- TD0_alpha_sel_arg1 );
- }
- break;
-
- case GL_MODULATE:
- if (unit == 0) {
- *reg = ( TD0_color_arg2_diffuse |
- TD0_color_sel_mul |
- TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_mul);
- }
- else {
- *reg = ( TD0_color_arg2_prevstage |
- TD0_color_alpha_prevstage |
- TD0_color_sel_mul |
- TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_mul);
- }
- break;
- case GL_DECAL:
- if (format == GL_RGB) {
- if (unit == 0) {
- *reg = (TD0_color_sel_arg1 |
- TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_arg2 );
- }
- else {
- *reg = (TD0_color_sel_arg1 |
- TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_arg2 );
- }
- }
- else if ( format == GL_RGBA ) {
-#if 0
- if (unit == 0) {
- /* this doesn't work */
- *reg = (TD0_color_arg2_diffuse |
- TD0_color_alpha_currtex |
- TD0_color_alpha2inv_enable |
- TD0_color_arg2mul_alpha2 |
- TD0_color_arg1mul_alpha1 |
- TD0_color_blend_enable |
- TD0_color_arg1add_mulout |
- TD0_color_arg2add_mulout |
- TD0_color_add_add |
- TD0_color_sel_mul |
- TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_arg2 );
- }
- else {
- *reg = (TD0_color_arg2_prevstage |
- TD0_color_alpha_currtex |
- TD0_color_alpha2inv_enable |
- TD0_color_arg2mul_alpha2 |
- TD0_color_arg1mul_alpha1 |
- TD0_color_add_add |
- TD0_color_sel_add |
- TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_arg2 );
- }
-#else
- /* s/w fallback, pretty sure we can't do in h/w */
- FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
- if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK )
- fprintf( stderr, "FALLBACK: GL_DECAL RGBA texture, unit=%d\n",
- unit );
-#endif
- }
- else {
- if (unit == 0) {
- *reg = ( TD0_color_arg2_diffuse |
- TD0_color_sel_arg2 |
- TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_arg2);
- }
- else {
- *reg = ( TD0_color_arg2_prevstage |
- TD0_color_sel_arg2 |
- TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_arg2);
- }
- }
- break;
-
- case GL_ADD:
- if (unit == 0) {
- if (format == GL_INTENSITY)
- *reg = ( TD0_color_arg2_diffuse |
- TD0_color_add_add |
- TD0_color_sel_add |
- TD0_alpha_arg2_diffuse |
- TD0_alpha_add_enable |
- TD0_alpha_sel_add);
- else if (format == GL_ALPHA)
- *reg = ( TD0_color_arg2_diffuse |
- TD0_color_sel_mul |
- TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_mul);
- else
- *reg = ( TD0_color_arg2_diffuse |
- TD0_color_add_add |
- TD0_color_sel_add |
- TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_mul);
- }
- else {
- if (format == GL_INTENSITY) {
- *reg = ( TD0_color_arg2_prevstage |
- TD0_color_add_add |
- TD0_color_sel_add |
- TD0_alpha_arg2_prevstage |
- TD0_alpha_add_enable |
- TD0_alpha_sel_add);
- }
- else if (format == GL_ALPHA) {
- *reg = ( TD0_color_arg2_prevstage |
- TD0_color_sel_mul |
- TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_mul);
- }
- else {
- *reg = ( TD0_color_arg2_prevstage |
- TD0_color_alpha_prevstage |
- TD0_color_add_add |
- TD0_color_sel_add |
- TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_mul);
- }
- }
- break;
-
- case GL_BLEND:
- if (format == GL_ALPHA) {
- *reg = ( TD0_color_arg2_diffuse |
- TD0_color_sel_mul |
- TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_mul);
- }
- else {
- FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
- if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK )
- fprintf( stderr, "FALLBACK: GL_BLEND envcolor=0x%08x\n",
- mmesa->envcolor );
-
- /* Do singletexture GL_BLEND with 'all ones' env-color
- * by using both texture units. Multitexture gl_blend
- * is a fallback.
- */
- if (unit == 0) {
- /* Part 1: R1 = Rf ( 1 - Rt )
- * A1 = Af At
- */
- *reg = ( TD0_color_arg2_diffuse |
- TD0_color_arg1_inv_enable |
- TD0_color_sel_mul |
- TD0_alpha_arg2_diffuse |
- TD0_alpha_sel_arg1);
- } else {
- /* Part 2: R2 = R1 + Rt
- * A2 = A1
- */
- *reg = ( TD0_color_arg2_prevstage |
- TD0_color_add_add |
- TD0_color_sel_add |
- TD0_alpha_arg2_prevstage |
- TD0_alpha_sel_arg2);
- }
- }
- break;
- default:
- break;
- }
-}
-
-
-
-static void mgaUpdateTextureObject( GLcontext *ctx, int hw_unit )
-{
- mgaTextureObjectPtr t;
- struct gl_texture_object *tObj;
- GLuint enabled;
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- GLuint gl_unit = mmesa->tmu_source[hw_unit];
-
-
- enabled = ctx->Texture.Unit[gl_unit]._ReallyEnabled;
- tObj = ctx->Texture.Unit[gl_unit]._Current;
-
- if (enabled != TEXTURE_2D_BIT) {
- if (enabled)
- FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
- return;
- }
-
- if (tObj->Image[tObj->BaseLevel]->Border > 0) {
- FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
- if ( MGA_DEBUG & DEBUG_VERBOSE_FALLBACK )
- fprintf( stderr, "FALLBACK: texture border\n" );
- return;
- }
-
- if ( !tObj->DriverData ) {
- mgaCreateTexObj( mmesa, tObj );
- if ( !tObj->DriverData ) {
- FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_TRUE );
- return;
- }
- }
-
- t = (mgaTextureObjectPtr)tObj->DriverData;
-
- if (t->dirty_images)
- mmesa->dirty |= (MGA_UPLOAD_TEX0IMAGE << hw_unit);
-
- mmesa->CurrentTexObj[hw_unit] = t;
- t->bound |= hw_unit+1;
-
-/* if (t->MemBlock) */
-/* mgaUpdateTexLRU( mmesa, t ); */
-
- t->setup.texctl2 &= ~TMC_dualtex_enable;
- if ((ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) &&
- (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT))
- t->setup.texctl2 |= TMC_dualtex_enable;
-
- t->setup.texctl2 &= ~TMC_specen_enable;
- if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
- t->setup.texctl2 |= TMC_specen_enable;
-}
-
-
+ t = CALLOC( sizeof( *t ) );
+ tObj->DriverData = t;
+ if ( t != NULL ) {
+ /* Initialize non-image-dependent parts of the state:
+ */
+ t->base.tObj = tObj;
+ t->setup.texctl = TMC_takey_1 | TMC_tamask_0;
+ t->setup.texctl2 = TMC_ckstransdis_enable;
+ t->setup.texfilter = (TF_minfilter_nrst
+ | TF_magfilter_nrst
+ | TF_filteralpha_enable
+ | TF_uvoffset_OGL);
+ t->border_fallback = GL_FALSE;
-/* The G400 is now programmed quite differently wrt texture environment.
- */
-void mgaUpdateTextureState( GLcontext *ctx )
-{
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- FALLBACK( ctx, MGA_FALLBACK_TEXTURE, GL_FALSE );
+ make_empty_list( & t->base );
- if (mmesa->CurrentTexObj[0]) {
- mmesa->CurrentTexObj[0]->bound = 0;
- mmesa->CurrentTexObj[0] = 0;
- }
-
- if (mmesa->CurrentTexObj[1]) {
- mmesa->CurrentTexObj[1]->bound = 0;
- mmesa->CurrentTexObj[1] = 0;
- }
-
- if (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) {
- mmesa->tmu_source[0] = 1;
- } else {
- mmesa->tmu_source[0] = 0;
- }
-
- if (MGA_IS_G400(mmesa)) {
- mgaUpdateTextureObject( ctx, 0 );
- mgaUpdateTextureEnvG400( ctx, 0 );
-
- mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0;
-
- if ((ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) &&
- (ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT)) {
- mgaUpdateTextureObject( ctx, 1 );
- mgaUpdateTextureEnvG400( ctx, 1 );
- mmesa->dirty |= MGA_UPLOAD_TEX1;
- }
- } else {
- mgaUpdateTextureObject( ctx, 0 );
- mgaUpdateTextureEnvG200( ctx );
+ mgaSetTexWrapping( t, tObj->WrapS, tObj->WrapT );
+ mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
+ mgaSetTexBorderColor( t, tObj->_BorderChan );
}
- mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_TEX0;
-
- mmesa->setup.dwgctl &= DC_opcod_MASK;
- mmesa->setup.dwgctl |= (ctx->Texture.Unit[0]._ReallyEnabled
- ? DC_opcod_texture_trap
- : DC_opcod_trap);
+ return( t );
}
-
-
static void mgaDDTexEnv( GLcontext *ctx, GLenum target,
GLenum pname, const GLfloat *param )
{
+ GLuint unit = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
mgaContextPtr mmesa = MGA_CONTEXT(ctx);
- if (pname == GL_TEXTURE_ENV_MODE) {
- /* force the texture state to be updated */
- FLUSH_BATCH( MGA_CONTEXT(ctx) );
- MGA_CONTEXT(ctx)->new_state |= (MGA_NEW_TEXTURE |
- MGA_NEW_ALPHA);
- }
- else if (pname == GL_TEXTURE_ENV_COLOR)
- {
- struct gl_texture_unit *texUnit =
- &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- GLfloat *fc = texUnit->EnvColor;
+ switch( pname ) {
+ case GL_TEXTURE_ENV_COLOR: {
GLubyte c[4];
- GLuint col;
+ GLuint envColor;
- COPY_4V(c, fc);
- col = mgaPackColor( mmesa->mgaScreen->cpp, c[0], c[1], c[2], c[3] );
- mmesa->envcolor = (c[3]<<24) | (c[0]<<16) | (c[1]<<8) | (c[2]);
+ UNCLAMPED_FLOAT_TO_RGBA_CHAN( c, texUnit->EnvColor );
+ envColor = mgaPackColor( mmesa->mgaScreen->cpp, c[0], c[1], c[2], c[3] );
+ mmesa->envcolor = PACK_COLOR_8888( c[3], c[0], c[1], c[2] );
- if (mmesa->setup.fcol != col) {
+ if (mmesa->setup.fcol != envColor) {
FLUSH_BATCH(mmesa);
- mmesa->setup.fcol = col;
+ mmesa->setup.fcol = envColor;
mmesa->dirty |= MGA_UPLOAD_CONTEXT;
mmesa->blend_flags &= ~MGA_BLEND_ENV_COLOR;
@@ -814,6 +354,8 @@ static void mgaDDTexEnv( GLcontext *ctx, GLenum target,
if (mmesa->envcolor != 0x0 && mmesa->envcolor != 0xffffffff)
mmesa->blend_flags |= MGA_BLEND_ENV_COLOR;
}
+ break;
+ }
}
}
@@ -826,14 +368,26 @@ static void mgaTexImage2D( GLcontext *ctx, GLenum target, GLint level,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage )
{
- mgaTextureObjectPtr t = (mgaTextureObjectPtr) texObj->DriverData;
- if (t) {
- mgaDestroyTexObj( MGA_CONTEXT(ctx), t );
- texObj->DriverData = 0;
+ driTextureObject * t = (driTextureObject *) texObj->DriverData;
+
+
+ if ( t != NULL ) {
+ driSwapOutTextureObject( t );
+ }
+ else {
+ t = (driTextureObject *) mgaAllocTexObj( texObj );
+ if ( t == NULL ) {
+ _mesa_error( ctx, GL_OUT_OF_MEMORY, "glTexImage2D" );
+ return;
+ }
}
+
_mesa_store_teximage2d( ctx, target, level, internalFormat,
width, height, border, format, type,
pixels, packing, texObj, texImage );
+ level -= t->firstLevel;
+ if (level >= 0)
+ t->dirty_images[0] |= (1UL << level);
}
static void mgaTexSubImage2D( GLcontext *ctx,
@@ -847,44 +401,59 @@ static void mgaTexSubImage2D( GLcontext *ctx,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage )
{
- mgaTextureObjectPtr t = (mgaTextureObjectPtr) texObj->DriverData;
- if (t) {
- mgaDestroyTexObj( MGA_CONTEXT(ctx), t );
- texObj->DriverData = 0;
+ driTextureObject * t = (driTextureObject *) texObj->DriverData;
+
+
+ assert( t != NULL ); /* this _should_ be true */
+ if ( t != NULL ) {
+ driSwapOutTextureObject( t );
+ }
+ else {
+ t = (driTextureObject *) mgaAllocTexObj( texObj );
+ if ( t == NULL ) {
+ _mesa_error( ctx, GL_OUT_OF_MEMORY, "glTexImage2D" );
+ return;
+ }
}
+
_mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
height, format, type, pixels, packing, texObj,
texImage);
-
+ level -= t->firstLevel;
+ if (level >= 0)
+ t->dirty_images[0] |= (1UL << level);
}
-
-
-/*
- * mgaTexParameter
- * This just changes variables and flags for a state update, which
- * will happen at the next mgaUpdateTextureState
+/**
+ * Changes variables and flags for a state update, which will happen at the
+ * next UpdateTextureState
*/
+
static void
mgaDDTexParameter( GLcontext *ctx, GLenum target,
struct gl_texture_object *tObj,
GLenum pname, const GLfloat *params )
{
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
+ mgaContextPtr mmesa = MGA_CONTEXT( ctx );
mgaTextureObjectPtr t;
t = (mgaTextureObjectPtr) tObj->DriverData;
- /* if we don't have a hardware texture, it will be automatically
- created with current state before it is used, so we don't have
- to do anything now */
- if ( !t || !t->bound || target != GL_TEXTURE_2D ) {
+ /* If we don't have a hardware texture, it will be automatically
+ * created with current state before it is used, so we don't have
+ * to do anything now
+ */
+
+ if ( (t == NULL)
+ || (target != GL_TEXTURE_2D) ) {
return;
}
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
+ driSwapOutTextureObject( (driTextureObject *) t );
+ /* FALLTHROUGH */
case GL_TEXTURE_MAG_FILTER:
FLUSH_BATCH(mmesa);
mgaSetTexFilter( t, tObj->MinFilter, tObj->MagFilter );
@@ -898,14 +467,24 @@ mgaDDTexParameter( GLcontext *ctx, GLenum target,
case GL_TEXTURE_BORDER_COLOR:
FLUSH_BATCH(mmesa);
- mgaSetTexBorderColor(t,tObj->_BorderChan);
+ mgaSetTexBorderColor(t, tObj->_BorderChan);
+ break;
+
+ case GL_TEXTURE_BASE_LEVEL:
+ case GL_TEXTURE_MAX_LEVEL:
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ /* This isn't the most efficient solution but there doesn't appear to
+ * be a nice alternative. Since there's no LOD clamping,
+ * we just have to rely on loading the right subset of mipmap levels
+ * to simulate a clamped LOD.
+ */
+ driSwapOutTextureObject( (driTextureObject *) t );
break;
default:
return;
}
-
- mmesa->new_state |= MGA_NEW_TEXTURE;
}
@@ -913,19 +492,11 @@ static void
mgaDDBindTexture( GLcontext *ctx, GLenum target,
struct gl_texture_object *tObj )
{
- mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- int unit = ctx->Texture.CurrentUnit;
-
- FLUSH_BATCH(mmesa);
-
- if (mmesa->CurrentTexObj[unit]) {
- mmesa->CurrentTexObj[unit]->bound &= ~(unit+1);
- mmesa->CurrentTexObj[unit] = 0;
+ if ( target == GL_TEXTURE_2D ) {
+ if ( tObj->DriverData == NULL ) {
+ mgaAllocTexObj( tObj );
+ }
}
-
- /* force the texture state to be updated
- */
- MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE;
}
@@ -933,53 +504,48 @@ static void
mgaDDDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
{
mgaContextPtr mmesa = MGA_CONTEXT( ctx );
- mgaTextureObjectPtr t = (mgaTextureObjectPtr)tObj->DriverData;
+ driTextureObject * t = (driTextureObject *) tObj->DriverData;
if ( t ) {
- if (mmesa) {
- if (t->bound) {
- FLUSH_BATCH(mmesa);
- if (t->bound & TEX_0) mmesa->CurrentTexObj[0] = 0;
- if (t->bound & TEX_1) mmesa->CurrentTexObj[1] = 0;
- }
- mmesa->new_state |= MGA_NEW_TEXTURE;
+ if ( mmesa ) {
+ FLUSH_BATCH( mmesa );
}
- mgaDestroyTexObj( mmesa, t );
+ driDestroyTextureObject( t );
}
}
-static GLboolean
-mgaDDIsTextureResident( GLcontext *ctx, struct gl_texture_object *t )
-{
- mgaTextureObjectPtr mt = (mgaTextureObjectPtr)t->DriverData;
- return mt && mt->MemBlock;
-}
-
-
void
mgaDDInitTextureFuncs( GLcontext *ctx )
{
- ctx->Driver.TexEnv = mgaDDTexEnv;
-
- ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
- ctx->Driver.TexImage1D = _mesa_store_teximage1d;
- ctx->Driver.TexImage2D = mgaTexImage2D;
- ctx->Driver.TexImage3D = _mesa_store_teximage3d;
- ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
- ctx->Driver.TexSubImage2D = mgaTexSubImage2D;
- ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
- ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
- ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
- ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
- ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
- ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
- ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
-
- ctx->Driver.BindTexture = mgaDDBindTexture;
- ctx->Driver.DeleteTexture = mgaDDDeleteTexture;
- ctx->Driver.TexParameter = mgaDDTexParameter;
- ctx->Driver.UpdateTexturePalette = 0;
- ctx->Driver.IsTextureResident = mgaDDIsTextureResident;
+ mgaContextPtr mmesa = MGA_CONTEXT(ctx);
+
+
+ ctx->Driver.ChooseTextureFormat = mgaChooseTextureFormat;
+ ctx->Driver.TexImage1D = _mesa_store_teximage1d;
+ ctx->Driver.TexImage2D = mgaTexImage2D;
+ ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+ ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
+ ctx->Driver.TexSubImage2D = mgaTexSubImage2D;
+ ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
+ ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
+ ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
+ ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
+ ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
+ ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
+ ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
+
+ ctx->Driver.BindTexture = mgaDDBindTexture;
+ ctx->Driver.CreateTexture = NULL; /* FIXME: Is this used??? */
+ ctx->Driver.DeleteTexture = mgaDDDeleteTexture;
+ ctx->Driver.IsTextureResident = driIsTextureResident;
+ ctx->Driver.PrioritizeTexture = NULL;
+ ctx->Driver.ActiveTexture = NULL;
+ ctx->Driver.UpdateTexturePalette = NULL;
+
+ ctx->Driver.TexEnv = mgaDDTexEnv;
+ ctx->Driver.TexParameter = mgaDDTexParameter;
+
+ driInitTextureObjects( ctx, & mmesa->swapped, DRI_TEXMGR_DO_TEXTURE_2D );
}