X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fmga%2Fmgatex.c;h=ca3dd4b01391c218db83f5ebd18a3346c4592b70;hb=09788ce10e354b3af6139c04a13b38df18632b13;hp=b4ee787e0b8af9dad8eb7a56ae29e6a5255b46dc;hpb=848ff108a06c1a8171bab879669c08c9274908f5;p=mesa.git diff --git a/src/mesa/drivers/dri/mga/mgatex.c b/src/mesa/drivers/dri/mga/mgatex.c index b4ee787e0b8..ca3dd4b0139 100644 --- a/src/mesa/drivers/dri/mga/mgatex.c +++ b/src/mesa/drivers/dri/mga/mgatex.c @@ -24,90 +24,92 @@ * Authors: * Keith Whitwell */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.c,v 1.14 2002/10/30 12:51:36 alanh Exp $ */ -#include -#include -#include +#include "main/glheader.h" +#include "main/mm.h" +#include "main/colormac.h" +#include "main/context.h" +#include "main/enums.h" +#include "main/simple_list.h" +#include "main/imports.h" +#include "main/macros.h" +#include "main/texstore.h" +#include "main/teximage.h" +#include "main/texobj.h" -#include "mm.h" #include "mgacontext.h" #include "mgatex.h" #include "mgaregs.h" -#include "mgatris.h" #include "mgaioctl.h" -#include "enums.h" -#include "simple_list.h" -/*#include "mem.h"*/ -#include "macros.h" -#include "texformat.h" -#include "texstore.h" -#include "teximage.h" +#include "xmlpool.h" -#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 ); -} - - -/* - * 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; + if ( is_clamp ) { + t->setup.texctl2 |= TMC_borderen_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; @@ -130,129 +132,104 @@ static void mgaSetTexFilter(mgaTextureObjectPtr t, GLenum minf, GLenum magf) /* See OpenGL 1.2 specification */ if (magf == GL_LINEAR && (minf == GL_NEAREST_MIPMAP_NEAREST || minf == GL_NEAREST_MIPMAP_LINEAR)) { - val |= (0x20 << TF_fthres_SHIFT); /* c = 0.5 */ + val |= MGA_FIELD( TF_fthres, 0x20 ); /* c = 0.5 */ } else { - val |= (0x10 << TF_fthres_SHIFT); /* c = 0 */ + val |= MGA_FIELD( TF_fthres, 0x10 ); /* c = 0 */ } - 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]) +static void mgaSetTexBorderColor(mgaTextureObjectPtr t, const GLfloat color[4]) { - t->setup.texbordercol = MGAPACKCOLOR8888(color[0],color[1], - color[2],color[3]); + GLubyte c[4]; + CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]); + t->setup.texbordercol = PACK_COLOR_8888(c[3], c[0], c[1], c[2] ); } -static GLint mgaChooseTexFormat( mgaContextPtr mmesa, - struct gl_texture_image *texImage, - GLenum format, GLenum type ) +static gl_format +mgaChooseTextureFormat( GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type ) { - 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. - */ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + const GLboolean do32bpt = + ( mmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32 ); + const GLboolean force16bpt = + ( mmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16 ); + (void) format; + + 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; - } + switch ( type ) { + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + return do32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB1555; + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return MESA_FORMAT_ARGB4444; + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + return MESA_FORMAT_ARGB1555; + default: + return do32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB4444; } - SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888, - TMC_tformat_tw12, _mesa_texformat_argb4444 ); - break; 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; + switch ( type ) { + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return MESA_FORMAT_ARGB4444; + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + return MESA_FORMAT_ARGB1555; + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + return MESA_FORMAT_RGB565; + default: + return do32bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_RGB565; } - SET_FORMAT_32BPT( TMC_tformat_tw32, _mesa_texformat_argb8888, - TMC_tformat_tw16, _mesa_texformat_rgb565 ); - break; - /* 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 !force16bpt ? + MESA_FORMAT_ARGB8888 : MESA_FORMAT_ARGB4444; case GL_RGBA4: case GL_RGBA2: - SET_FORMAT( TMC_tformat_tw12, _mesa_texformat_argb4444 ); - break; + return MESA_FORMAT_ARGB4444; case GL_RGB5_A1: - SET_FORMAT( TMC_tformat_tw15, _mesa_texformat_argb1555 ); - break; + return MESA_FORMAT_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 !force16bpt ? MESA_FORMAT_ARGB8888 : MESA_FORMAT_RGB565; case GL_RGB5: case GL_RGB4: case GL_R3_G3_B2: - SET_FORMAT( TMC_tformat_tw16, _mesa_texformat_rgb565 ); - break; + return MESA_FORMAT_RGB565; case GL_ALPHA: case GL_ALPHA4: @@ -261,8 +238,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 MGA_IS_G400(mmesa) ? MESA_FORMAT_AL88 : MESA_FORMAT_ARGB4444; case 1: case GL_LUMINANCE: @@ -272,8 +248,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 MGA_IS_G400(mmesa) ? MESA_FORMAT_AL88 : MESA_FORMAT_RGB565; case 2: case GL_LUMINANCE_ALPHA: @@ -285,8 +260,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 MGA_IS_G400(mmesa) ? MESA_FORMAT_AL88 : MESA_FORMAT_ARGB4444; case GL_INTENSITY: case GL_INTENSITY4: @@ -295,8 +269,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 MGA_IS_G400(mmesa) ? MESA_FORMAT_I8 : MESA_FORMAT_ARGB4444; + + case GL_YCBCR_MESA: + if (MGA_IS_G400(mmesa) && + (type == GL_UNSIGNED_SHORT_8_8_APPLE || + type == GL_UNSIGNED_BYTE)) + return MESA_FORMAT_YCBCR; + else + return MESA_FORMAT_YCBCR_REV; case GL_COLOR_INDEX: case GL_COLOR_INDEX1_EXT: @@ -305,515 +286,71 @@ 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_FORMAT_CI8; default: - fprintf( stderr, "bad texture format in mgaChooseTexFormat() %d", - texImage->IntFormat ); - return -1; + _mesa_problem( ctx, "unexpected texture format in %s", __FUNCTION__ ); + return MESA_FORMAT_NONE; } - texImage->TexFormat = texFormat; - - return ret; + return MESA_FORMAT_NONE; /* 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<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_filteralpha_enable | TF_uvoffset_OGL; + t->border_fallback = GL_FALSE; + t->texenv_fallback = GL_FALSE; + make_empty_list( & t->base ); -/* 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 ); - - 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->BorderColor.f ); } - 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, +static void mgaTexEnv( 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); + switch( pname ) { + case GL_TEXTURE_ENV_COLOR: { + GLubyte c[4]; - 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); + UNCLAMPED_FLOAT_TO_RGBA_CHAN( c, texUnit->EnvColor ); + mmesa->envcolor[unit] = PACK_COLOR_8888( c[3], c[0], c[1], c[2] ); + break; } - else if (pname == GL_TEXTURE_ENV_COLOR) - { - struct gl_texture_unit *texUnit = - &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - GLfloat *fc = texUnit->EnvColor; - GLubyte c[4]; - GLuint col; - - 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]); - - if (mmesa->setup.fcol != col) { - FLUSH_BATCH(mmesa); - mmesa->setup.fcol = col; - mmesa->dirty |= MGA_UPLOAD_CONTEXT; - - mmesa->blend_flags &= ~MGA_BLEND_ENV_COLOR; - - /* Actually just require all four components to be - * equal. This permits a single-pass GL_BLEND. - * - * More complex multitexture/multipass fallbacks - * for blend can be done later. - */ - if (mmesa->envcolor != 0x0 && mmesa->envcolor != 0xffffffff) - mmesa->blend_flags |= MGA_BLEND_ENV_COLOR; - } } } @@ -826,14 +363,25 @@ 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 +395,56 @@ 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 ); /* 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, +mgaTexParameter( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLenum pname, const GLfloat *params ) { mgaContextPtr mmesa = MGA_CONTEXT( ctx ); - mgaTextureObjectPtr t; - - t = (mgaTextureObjectPtr) tObj->DriverData; + mgaTextureObjectPtr 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 && + target != GL_TEXTURE_RECTANGLE_NV) ) { 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,88 +458,83 @@ mgaDDTexParameter( GLcontext *ctx, GLenum target, case GL_TEXTURE_BORDER_COLOR: FLUSH_BATCH(mmesa); - mgaSetTexBorderColor(t,tObj->_BorderChan); + mgaSetTexBorderColor(t, tObj->BorderColor.f); + 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; } static void -mgaDDBindTexture( GLcontext *ctx, GLenum target, +mgaBindTexture( 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; - } - - /* force the texture state to be updated - */ - MGA_CONTEXT(ctx)->new_state |= MGA_NEW_TEXTURE; + assert( (target != GL_TEXTURE_2D && target != GL_TEXTURE_RECTANGLE_NV) || + (tObj->DriverData != NULL) ); } static void -mgaDDDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) +mgaDeleteTexture( 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 ); } + + /* Free mipmap images and the texture object itself */ + _mesa_delete_texture_object(ctx, tObj); } -static GLboolean -mgaDDIsTextureResident( GLcontext *ctx, struct gl_texture_object *t ) +/** + * 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 * +mgaNewTextureObject( GLcontext *ctx, GLuint name, GLenum target ) { - mgaTextureObjectPtr mt = (mgaTextureObjectPtr)t->DriverData; - return mt && mt->MemBlock; + struct gl_texture_object *obj; + obj = _mesa_new_texture_object(ctx, name, target); + mgaAllocTexObj( obj ); + return obj; } void -mgaDDInitTextureFuncs( GLcontext *ctx ) +mgaInitTextureFuncs( struct dd_function_table *functions ) { - 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; + functions->ChooseTextureFormat = mgaChooseTextureFormat; + functions->TexImage2D = mgaTexImage2D; + functions->TexSubImage2D = mgaTexSubImage2D; + functions->BindTexture = mgaBindTexture; + functions->NewTextureObject = mgaNewTextureObject; + functions->DeleteTexture = mgaDeleteTexture; + functions->IsTextureResident = driIsTextureResident; + functions->TexEnv = mgaTexEnv; + functions->TexParameter = mgaTexParameter; }