summaryrefslogtreecommitdiff
path: root/i915/i830_tex.c
diff options
context:
space:
mode:
Diffstat (limited to 'i915/i830_tex.c')
-rw-r--r--i915/i830_tex.c356
1 files changed, 356 insertions, 0 deletions
diff --git a/i915/i830_tex.c b/i915/i830_tex.c
new file mode 100644
index 0000000..3c4aedb
--- /dev/null
+++ b/i915/i830_tex.c
@@ -0,0 +1,356 @@
+/**************************************************************************
+ *
+ * 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 "simple_list.h"
+#include "enums.h"
+#include "image.h"
+#include "texstore.h"
+#include "texformat.h"
+#include "texmem.h"
+#include "swrast/swrast.h"
+
+#include "mm.h"
+
+#include "intel_ioctl.h"
+
+#include "i830_context.h"
+#include "i830_reg.h"
+
+
+
+
+/**
+ * Set the texture wrap modes.
+ *
+ * The i830M (and related graphics cores) do not support GL_CLAMP. The Intel
+ * drivers for "other operating systems" implement GL_CLAMP as
+ * GL_CLAMP_TO_EDGE, so the same is done here.
+ *
+ * \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
+ */
+static void i830SetTexWrapping(i830TextureObjectPtr tex,
+ GLenum swrap,
+ GLenum twrap)
+{
+ tex->Setup[I830_TEXREG_MCS] &= ~(TEXCOORD_ADDR_U_MASK|TEXCOORD_ADDR_V_MASK);
+
+ switch( swrap ) {
+ case GL_REPEAT:
+ tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP);
+ break;
+ case GL_CLAMP:
+ case GL_CLAMP_TO_EDGE:
+ tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP);
+ break;
+ case GL_CLAMP_TO_BORDER:
+ tex->Setup[I830_TEXREG_MCS] |=
+ TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP_BORDER);
+ break;
+ case GL_MIRRORED_REPEAT:
+ tex->Setup[I830_TEXREG_MCS] |=
+ TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_MIRROR);
+ break;
+ default:
+ break;
+ }
+
+ switch( twrap ) {
+ case GL_REPEAT:
+ tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP);
+ break;
+ case GL_CLAMP:
+ case GL_CLAMP_TO_EDGE:
+ tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP);
+ break;
+ case GL_CLAMP_TO_BORDER:
+ tex->Setup[I830_TEXREG_MCS] |=
+ TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP_BORDER);
+ break;
+ case GL_MIRRORED_REPEAT:
+ tex->Setup[I830_TEXREG_MCS] |=
+ TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_MIRROR);
+ break;
+ default:
+ break;
+ }
+}
+
+
+/**
+ * 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
+ * \param bias LOD bias for this texture unit.
+ */
+
+static void i830SetTexFilter( i830TextureObjectPtr t, GLenum minf, GLenum magf,
+ GLfloat maxanisotropy )
+{
+ int minFilt = 0, mipFilt = 0, magFilt = 0;
+
+ if(INTEL_DEBUG&DEBUG_DRI)
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+ if ( maxanisotropy > 1.0 ) {
+ minFilt = FILTER_ANISOTROPIC;
+ magFilt = FILTER_ANISOTROPIC;
+ }
+ else {
+ switch (minf) {
+ 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;
+ }
+
+ switch (magf) {
+ case GL_NEAREST:
+ magFilt = FILTER_NEAREST;
+ break;
+ case GL_LINEAR:
+ magFilt = FILTER_LINEAR;
+ break;
+ default:
+ break;
+ }
+ }
+
+ t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_FILTER_MASK;
+ t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIP_FILTER_MASK;
+ t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAG_FILTER_MASK;
+ t->Setup[I830_TEXREG_TM0S3] |= ((minFilt << TM0S3_MIN_FILTER_SHIFT) |
+ (mipFilt << TM0S3_MIP_FILTER_SHIFT) |
+ (magFilt << TM0S3_MAG_FILTER_SHIFT));
+}
+
+static void i830SetTexBorderColor(i830TextureObjectPtr t, GLubyte color[4])
+{
+ if(INTEL_DEBUG&DEBUG_DRI)
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+ t->Setup[I830_TEXREG_TM0S4] =
+ INTEL_PACKCOLOR8888(color[0],color[1],color[2],color[3]);
+}
+
+
+/**
+ * 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 i830AllocTexObj( struct gl_texture_object *texObj )
+{
+ i830TextureObjectPtr t = CALLOC_STRUCT( i830_texture_object );
+ if ( !t )
+ return NULL;
+
+ texObj->DriverData = t;
+ t->intel.base.tObj = texObj;
+ t->intel.dirty = I830_UPLOAD_TEX_ALL;
+ make_empty_list( &t->intel.base );
+
+ t->Setup[I830_TEXREG_TM0LI] = 0; /* not used */
+ t->Setup[I830_TEXREG_TM0S0] = 0;
+ t->Setup[I830_TEXREG_TM0S1] = 0;
+ t->Setup[I830_TEXREG_TM0S2] = 0;
+ t->Setup[I830_TEXREG_TM0S3] = 0;
+ t->Setup[I830_TEXREG_MCS] = (_3DSTATE_MAP_COORD_SET_CMD |
+ MAP_UNIT(0) |
+ ENABLE_TEXCOORD_PARAMS |
+ TEXCOORDS_ARE_NORMAL |
+ TEXCOORDTYPE_CARTESIAN |
+ ENABLE_ADDR_V_CNTL |
+ TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) |
+ ENABLE_ADDR_U_CNTL |
+ TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP));
+
+
+ i830SetTexWrapping( t, texObj->WrapS, texObj->WrapT );
+ i830SetTexFilter( t, texObj->MinFilter, texObj->MagFilter,
+ texObj->MaxAnisotropy );
+ i830SetTexBorderColor( t, texObj->_BorderChan );
+
+ return &t->intel;
+}
+
+
+static void i830TexParameter( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj,
+ GLenum pname, const GLfloat *params )
+{
+ i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData;
+ if (!t)
+ return;
+
+ switch (pname) {
+ case GL_TEXTURE_MIN_FILTER:
+ case GL_TEXTURE_MAG_FILTER:
+ case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+ i830SetTexFilter( t, tObj->MinFilter, tObj->MagFilter,
+ tObj->MaxAnisotropy);
+ break;
+
+ case GL_TEXTURE_WRAP_S:
+ case GL_TEXTURE_WRAP_T:
+ i830SetTexWrapping( t, tObj->WrapS, tObj->WrapT );
+ break;
+
+ case GL_TEXTURE_BORDER_COLOR:
+ i830SetTexBorderColor( t, tObj->_BorderChan );
+ break;
+
+ case GL_TEXTURE_BASE_LEVEL:
+ case GL_TEXTURE_MAX_LEVEL:
+ case GL_TEXTURE_MIN_LOD:
+ case GL_TEXTURE_MAX_LOD:
+ /* The i830 and its successors can do a lot of this without
+ * reloading the textures. A project for someone?
+ */
+ intelFlush( ctx );
+ driSwapOutTextureObject( (driTextureObject *) t );
+ break;
+
+ default:
+ return;
+ }
+
+ t->intel.dirty = I830_UPLOAD_TEX_ALL;
+}
+
+
+static void i830TexEnv( GLcontext *ctx, GLenum target,
+ GLenum pname, const GLfloat *param )
+{
+ i830ContextPtr i830 = I830_CONTEXT( ctx );
+ GLuint unit = ctx->Texture.CurrentUnit;
+
+ switch (pname) {
+ case GL_TEXTURE_ENV_COLOR:
+#if 0
+ {
+ GLubyte r, g, b, a;
+ GLuint col;
+
+ UNCLAMPED_FLOAT_TO_UBYTE(r, param[RCOMP]);
+ UNCLAMPED_FLOAT_TO_UBYTE(g, param[GCOMP]);
+ UNCLAMPED_FLOAT_TO_UBYTE(b, param[BCOMP]);
+ UNCLAMPED_FLOAT_TO_UBYTE(a, param[ACOMP]);
+
+ col = ((a << 24) | (r << 16) | (g << 8) | b);
+
+ if (col != i830->state.TexEnv[unit][I830_TEXENVREG_COL1]) {
+ I830_STATECHANGE(i830, I830_UPLOAD_TEXENV);
+ i830->state.TexEnv[unit][I830_TEXENVREG_COL1] = col;
+ }
+
+ break;
+ }
+#endif
+ case GL_TEXTURE_ENV_MODE:
+ case GL_COMBINE_RGB:
+ case GL_COMBINE_ALPHA:
+ case GL_SOURCE0_RGB:
+ case GL_SOURCE1_RGB:
+ case GL_SOURCE2_RGB:
+ case GL_SOURCE0_ALPHA:
+ case GL_SOURCE1_ALPHA:
+ case GL_SOURCE2_ALPHA:
+ case GL_OPERAND0_RGB:
+ case GL_OPERAND1_RGB:
+ case GL_OPERAND2_RGB:
+ case GL_OPERAND0_ALPHA:
+ case GL_OPERAND1_ALPHA:
+ case GL_OPERAND2_ALPHA:
+ case GL_RGB_SCALE:
+ case GL_ALPHA_SCALE:
+ break;
+
+ case GL_TEXTURE_LOD_BIAS: {
+ int b = (int) ((*param) * 16.0);
+ if (b > 63) b = 63;
+ if (b < -64) b = -64;
+ I830_STATECHANGE(i830, I830_UPLOAD_TEX(unit));
+ i830->state.Tex[unit][I830_TEXREG_TM0S3] &= ~TM0S3_LOD_BIAS_MASK;
+ i830->state.Tex[unit][I830_TEXREG_TM0S3] |=
+ ((b << TM0S3_LOD_BIAS_SHIFT) & TM0S3_LOD_BIAS_MASK);
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+static void i830BindTexture( GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj )
+{
+ i830TextureObjectPtr tex;
+
+ if (!texObj->DriverData)
+ i830AllocTexObj( texObj );
+
+ tex = (i830TextureObjectPtr)texObj->DriverData;
+}
+
+
+
+void i830InitTextureFuncs( struct dd_function_table *functions )
+{
+ functions->BindTexture = i830BindTexture;
+ functions->TexEnv = i830TexEnv;
+ functions->TexParameter = i830TexParameter;
+}