1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
31 #include "simple_list.h"
35 #include "texformat.h"
37 #include "swrast/swrast.h"
41 #include "intel_ioctl.h"
43 #include "i830_context.h"
50 * Set the texture wrap modes.
52 * The i830M (and related graphics cores) do not support GL_CLAMP. The Intel
53 * drivers for "other operating systems" implement GL_CLAMP as
54 * GL_CLAMP_TO_EDGE, so the same is done here.
56 * \param t Texture object whose wrap modes are to be set
57 * \param swrap Wrap mode for the \a s texture coordinate
58 * \param twrap Wrap mode for the \a t texture coordinate
60 static void i830SetTexWrapping(i830TextureObjectPtr tex
,
64 tex
->Setup
[I830_TEXREG_MCS
] &= ~(TEXCOORD_ADDR_U_MASK
|TEXCOORD_ADDR_V_MASK
);
68 tex
->Setup
[I830_TEXREG_MCS
] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP
);
71 case GL_CLAMP_TO_EDGE
:
72 tex
->Setup
[I830_TEXREG_MCS
] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP
);
74 case GL_CLAMP_TO_BORDER
:
75 tex
->Setup
[I830_TEXREG_MCS
] |=
76 TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP_BORDER
);
78 case GL_MIRRORED_REPEAT
:
79 tex
->Setup
[I830_TEXREG_MCS
] |=
80 TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_MIRROR
);
88 tex
->Setup
[I830_TEXREG_MCS
] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP
);
91 case GL_CLAMP_TO_EDGE
:
92 tex
->Setup
[I830_TEXREG_MCS
] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP
);
94 case GL_CLAMP_TO_BORDER
:
95 tex
->Setup
[I830_TEXREG_MCS
] |=
96 TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP_BORDER
);
98 case GL_MIRRORED_REPEAT
:
99 tex
->Setup
[I830_TEXREG_MCS
] |=
100 TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_MIRROR
);
109 * Set the texture magnification and minification modes.
111 * \param t Texture whose filter modes are to be set
112 * \param minf Texture minification mode
113 * \param magf Texture magnification mode
114 * \param bias LOD bias for this texture unit.
117 static void i830SetTexFilter( i830TextureObjectPtr t
, GLenum minf
, GLenum magf
,
118 GLfloat maxanisotropy
)
120 int minFilt
= 0, mipFilt
= 0, magFilt
= 0;
122 if(INTEL_DEBUG
&DEBUG_DRI
)
123 fprintf(stderr
, "%s\n", __FUNCTION__
);
125 if ( maxanisotropy
> 1.0 ) {
126 minFilt
= FILTER_ANISOTROPIC
;
127 magFilt
= FILTER_ANISOTROPIC
;
132 minFilt
= FILTER_NEAREST
;
133 mipFilt
= MIPFILTER_NONE
;
136 minFilt
= FILTER_LINEAR
;
137 mipFilt
= MIPFILTER_NONE
;
139 case GL_NEAREST_MIPMAP_NEAREST
:
140 minFilt
= FILTER_NEAREST
;
141 mipFilt
= MIPFILTER_NEAREST
;
143 case GL_LINEAR_MIPMAP_NEAREST
:
144 minFilt
= FILTER_LINEAR
;
145 mipFilt
= MIPFILTER_NEAREST
;
147 case GL_NEAREST_MIPMAP_LINEAR
:
148 minFilt
= FILTER_NEAREST
;
149 mipFilt
= MIPFILTER_LINEAR
;
151 case GL_LINEAR_MIPMAP_LINEAR
:
152 minFilt
= FILTER_LINEAR
;
153 mipFilt
= MIPFILTER_LINEAR
;
161 magFilt
= FILTER_NEAREST
;
164 magFilt
= FILTER_LINEAR
;
171 t
->Setup
[I830_TEXREG_TM0S3
] &= ~TM0S3_MIN_FILTER_MASK
;
172 t
->Setup
[I830_TEXREG_TM0S3
] &= ~TM0S3_MIP_FILTER_MASK
;
173 t
->Setup
[I830_TEXREG_TM0S3
] &= ~TM0S3_MAG_FILTER_MASK
;
174 t
->Setup
[I830_TEXREG_TM0S3
] |= ((minFilt
<< TM0S3_MIN_FILTER_SHIFT
) |
175 (mipFilt
<< TM0S3_MIP_FILTER_SHIFT
) |
176 (magFilt
<< TM0S3_MAG_FILTER_SHIFT
));
179 static void i830SetTexBorderColor(i830TextureObjectPtr t
, GLubyte color
[4])
181 if(INTEL_DEBUG
&DEBUG_DRI
)
182 fprintf(stderr
, "%s\n", __FUNCTION__
);
184 t
->Setup
[I830_TEXREG_TM0S4
] =
185 INTEL_PACKCOLOR8888(color
[0],color
[1],color
[2],color
[3]);
190 * Allocate space for and load the mesa images into the texture memory block.
191 * This will happen before drawing with a new texture, or drawing with a
192 * texture after it was swapped out or teximaged again.
195 intelTextureObjectPtr
i830AllocTexObj( struct gl_texture_object
*texObj
)
197 i830TextureObjectPtr t
= CALLOC_STRUCT( i830_texture_object
);
201 texObj
->DriverData
= t
;
202 t
->intel
.base
.tObj
= texObj
;
203 t
->intel
.dirty
= I830_UPLOAD_TEX_ALL
;
204 make_empty_list( &t
->intel
.base
);
206 t
->Setup
[I830_TEXREG_TM0LI
] = 0; /* not used */
207 t
->Setup
[I830_TEXREG_TM0S0
] = 0;
208 t
->Setup
[I830_TEXREG_TM0S1
] = 0;
209 t
->Setup
[I830_TEXREG_TM0S2
] = 0;
210 t
->Setup
[I830_TEXREG_TM0S3
] = 0;
211 t
->Setup
[I830_TEXREG_MCS
] = (_3DSTATE_MAP_COORD_SET_CMD
|
213 ENABLE_TEXCOORD_PARAMS
|
214 TEXCOORDS_ARE_NORMAL
|
215 TEXCOORDTYPE_CARTESIAN
|
217 TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP
) |
219 TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP
));
222 i830SetTexWrapping( t
, texObj
->WrapS
, texObj
->WrapT
);
223 i830SetTexFilter( t
, texObj
->MinFilter
, texObj
->MagFilter
,
224 texObj
->MaxAnisotropy
);
225 i830SetTexBorderColor( t
, texObj
->_BorderChan
);
231 static void i830TexParameter( GLcontext
*ctx
, GLenum target
,
232 struct gl_texture_object
*tObj
,
233 GLenum pname
, const GLfloat
*params
)
235 i830TextureObjectPtr t
= (i830TextureObjectPtr
) tObj
->DriverData
;
240 case GL_TEXTURE_MIN_FILTER
:
241 case GL_TEXTURE_MAG_FILTER
:
242 case GL_TEXTURE_MAX_ANISOTROPY_EXT
:
243 i830SetTexFilter( t
, tObj
->MinFilter
, tObj
->MagFilter
,
244 tObj
->MaxAnisotropy
);
247 case GL_TEXTURE_WRAP_S
:
248 case GL_TEXTURE_WRAP_T
:
249 i830SetTexWrapping( t
, tObj
->WrapS
, tObj
->WrapT
);
252 case GL_TEXTURE_BORDER_COLOR
:
253 i830SetTexBorderColor( t
, tObj
->_BorderChan
);
256 case GL_TEXTURE_BASE_LEVEL
:
257 case GL_TEXTURE_MAX_LEVEL
:
258 case GL_TEXTURE_MIN_LOD
:
259 case GL_TEXTURE_MAX_LOD
:
260 /* The i830 and its successors can do a lot of this without
261 * reloading the textures. A project for someone?
264 driSwapOutTextureObject( (driTextureObject
*) t
);
271 t
->intel
.dirty
= I830_UPLOAD_TEX_ALL
;
275 static void i830TexEnv( GLcontext
*ctx
, GLenum target
,
276 GLenum pname
, const GLfloat
*param
)
278 i830ContextPtr i830
= I830_CONTEXT( ctx
);
279 GLuint unit
= ctx
->Texture
.CurrentUnit
;
282 case GL_TEXTURE_ENV_COLOR
:
288 UNCLAMPED_FLOAT_TO_UBYTE(r
, param
[RCOMP
]);
289 UNCLAMPED_FLOAT_TO_UBYTE(g
, param
[GCOMP
]);
290 UNCLAMPED_FLOAT_TO_UBYTE(b
, param
[BCOMP
]);
291 UNCLAMPED_FLOAT_TO_UBYTE(a
, param
[ACOMP
]);
293 col
= ((a
<< 24) | (r
<< 16) | (g
<< 8) | b
);
295 if (col
!= i830
->state
.TexEnv
[unit
][I830_TEXENVREG_COL1
]) {
296 I830_STATECHANGE(i830
, I830_UPLOAD_TEXENV
);
297 i830
->state
.TexEnv
[unit
][I830_TEXENVREG_COL1
] = col
;
303 case GL_TEXTURE_ENV_MODE
:
305 case GL_COMBINE_ALPHA
:
309 case GL_SOURCE0_ALPHA
:
310 case GL_SOURCE1_ALPHA
:
311 case GL_SOURCE2_ALPHA
:
312 case GL_OPERAND0_RGB
:
313 case GL_OPERAND1_RGB
:
314 case GL_OPERAND2_RGB
:
315 case GL_OPERAND0_ALPHA
:
316 case GL_OPERAND1_ALPHA
:
317 case GL_OPERAND2_ALPHA
:
322 case GL_TEXTURE_LOD_BIAS
: {
323 int b
= (int) ((*param
) * 16.0);
325 if (b
< -64) b
= -64;
326 I830_STATECHANGE(i830
, I830_UPLOAD_TEX(unit
));
327 i830
->state
.Tex
[unit
][I830_TEXREG_TM0S3
] &= ~TM0S3_LOD_BIAS_MASK
;
328 i830
->state
.Tex
[unit
][I830_TEXREG_TM0S3
] |=
329 ((b
<< TM0S3_LOD_BIAS_SHIFT
) & TM0S3_LOD_BIAS_MASK
);
341 void i830InitTextureFuncs( struct dd_function_table
*functions
)
343 functions
->TexEnv
= i830TexEnv
;
344 functions
->TexParameter
= i830TexParameter
;