Add PCI IDs for the G33, Q33, and Q35 chipsets.
[mesa.git] / src / mesa / drivers / dri / i915 / i830_tex.c
1 /**************************************************************************
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
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:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
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.
25 *
26 **************************************************************************/
27
28 #include "glheader.h"
29 #include "mtypes.h"
30 #include "imports.h"
31 #include "simple_list.h"
32 #include "enums.h"
33 #include "image.h"
34 #include "texstore.h"
35 #include "texformat.h"
36 #include "texmem.h"
37 #include "swrast/swrast.h"
38
39 #include "mm.h"
40
41 #include "intel_ioctl.h"
42
43 #include "i830_context.h"
44 #include "i830_reg.h"
45
46
47
48
49 /**
50 * Set the texture wrap modes.
51 *
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.
55 *
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
59 */
60 static void i830SetTexWrapping(i830TextureObjectPtr tex,
61 GLenum swrap,
62 GLenum twrap)
63 {
64 tex->Setup[I830_TEXREG_MCS] &= ~(TEXCOORD_ADDR_U_MASK|TEXCOORD_ADDR_V_MASK);
65
66 switch( swrap ) {
67 case GL_REPEAT:
68 tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP);
69 break;
70 case GL_CLAMP:
71 case GL_CLAMP_TO_EDGE:
72 tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP);
73 break;
74 case GL_CLAMP_TO_BORDER:
75 tex->Setup[I830_TEXREG_MCS] |=
76 TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_CLAMP_BORDER);
77 break;
78 case GL_MIRRORED_REPEAT:
79 tex->Setup[I830_TEXREG_MCS] |=
80 TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_MIRROR);
81 break;
82 default:
83 break;
84 }
85
86 switch( twrap ) {
87 case GL_REPEAT:
88 tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP);
89 break;
90 case GL_CLAMP:
91 case GL_CLAMP_TO_EDGE:
92 tex->Setup[I830_TEXREG_MCS] |= TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP);
93 break;
94 case GL_CLAMP_TO_BORDER:
95 tex->Setup[I830_TEXREG_MCS] |=
96 TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_CLAMP_BORDER);
97 break;
98 case GL_MIRRORED_REPEAT:
99 tex->Setup[I830_TEXREG_MCS] |=
100 TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_MIRROR);
101 break;
102 default:
103 break;
104 }
105 }
106
107
108 /**
109 * Set the texture magnification and minification modes.
110 *
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.
115 */
116
117 static void i830SetTexFilter( i830TextureObjectPtr t, GLenum minf, GLenum magf,
118 GLfloat maxanisotropy )
119 {
120 int minFilt = 0, mipFilt = 0, magFilt = 0;
121
122 if(INTEL_DEBUG&DEBUG_DRI)
123 fprintf(stderr, "%s\n", __FUNCTION__);
124
125 if ( maxanisotropy > 1.0 ) {
126 minFilt = FILTER_ANISOTROPIC;
127 magFilt = FILTER_ANISOTROPIC;
128 }
129 else {
130 switch (minf) {
131 case GL_NEAREST:
132 minFilt = FILTER_NEAREST;
133 mipFilt = MIPFILTER_NONE;
134 break;
135 case GL_LINEAR:
136 minFilt = FILTER_LINEAR;
137 mipFilt = MIPFILTER_NONE;
138 break;
139 case GL_NEAREST_MIPMAP_NEAREST:
140 minFilt = FILTER_NEAREST;
141 mipFilt = MIPFILTER_NEAREST;
142 break;
143 case GL_LINEAR_MIPMAP_NEAREST:
144 minFilt = FILTER_LINEAR;
145 mipFilt = MIPFILTER_NEAREST;
146 break;
147 case GL_NEAREST_MIPMAP_LINEAR:
148 minFilt = FILTER_NEAREST;
149 mipFilt = MIPFILTER_LINEAR;
150 break;
151 case GL_LINEAR_MIPMAP_LINEAR:
152 minFilt = FILTER_LINEAR;
153 mipFilt = MIPFILTER_LINEAR;
154 break;
155 default:
156 break;
157 }
158
159 switch (magf) {
160 case GL_NEAREST:
161 magFilt = FILTER_NEAREST;
162 break;
163 case GL_LINEAR:
164 magFilt = FILTER_LINEAR;
165 break;
166 default:
167 break;
168 }
169 }
170
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));
177 }
178
179 static void i830SetTexBorderColor(i830TextureObjectPtr t, GLubyte color[4])
180 {
181 if(INTEL_DEBUG&DEBUG_DRI)
182 fprintf(stderr, "%s\n", __FUNCTION__);
183
184 t->Setup[I830_TEXREG_TM0S4] =
185 INTEL_PACKCOLOR8888(color[0],color[1],color[2],color[3]);
186 }
187
188
189 /**
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.
193 */
194
195 intelTextureObjectPtr i830AllocTexObj( struct gl_texture_object *texObj )
196 {
197 i830TextureObjectPtr t = CALLOC_STRUCT( i830_texture_object );
198 if ( !t )
199 return NULL;
200
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 );
205
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 |
212 MAP_UNIT(0) |
213 ENABLE_TEXCOORD_PARAMS |
214 TEXCOORDS_ARE_NORMAL |
215 TEXCOORDTYPE_CARTESIAN |
216 ENABLE_ADDR_V_CNTL |
217 TEXCOORD_ADDR_V_MODE(TEXCOORDMODE_WRAP) |
218 ENABLE_ADDR_U_CNTL |
219 TEXCOORD_ADDR_U_MODE(TEXCOORDMODE_WRAP));
220
221
222 i830SetTexWrapping( t, texObj->WrapS, texObj->WrapT );
223 i830SetTexFilter( t, texObj->MinFilter, texObj->MagFilter,
224 texObj->MaxAnisotropy );
225 i830SetTexBorderColor( t, texObj->_BorderChan );
226
227 return &t->intel;
228 }
229
230
231 static void i830TexParameter( GLcontext *ctx, GLenum target,
232 struct gl_texture_object *tObj,
233 GLenum pname, const GLfloat *params )
234 {
235 i830TextureObjectPtr t = (i830TextureObjectPtr) tObj->DriverData;
236 if (!t)
237 return;
238
239 switch (pname) {
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);
245 break;
246
247 case GL_TEXTURE_WRAP_S:
248 case GL_TEXTURE_WRAP_T:
249 i830SetTexWrapping( t, tObj->WrapS, tObj->WrapT );
250 break;
251
252 case GL_TEXTURE_BORDER_COLOR:
253 i830SetTexBorderColor( t, tObj->_BorderChan );
254 break;
255
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?
262 */
263 intelFlush( ctx );
264 driSwapOutTextureObject( (driTextureObject *) t );
265 break;
266
267 default:
268 return;
269 }
270
271 t->intel.dirty = I830_UPLOAD_TEX_ALL;
272 }
273
274
275 static void i830TexEnv( GLcontext *ctx, GLenum target,
276 GLenum pname, const GLfloat *param )
277 {
278 i830ContextPtr i830 = I830_CONTEXT( ctx );
279 GLuint unit = ctx->Texture.CurrentUnit;
280
281 switch (pname) {
282 case GL_TEXTURE_ENV_COLOR:
283 #if 0
284 {
285 GLubyte r, g, b, a;
286 GLuint col;
287
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]);
292
293 col = ((a << 24) | (r << 16) | (g << 8) | b);
294
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;
298 }
299
300 break;
301 }
302 #endif
303 case GL_TEXTURE_ENV_MODE:
304 case GL_COMBINE_RGB:
305 case GL_COMBINE_ALPHA:
306 case GL_SOURCE0_RGB:
307 case GL_SOURCE1_RGB:
308 case GL_SOURCE2_RGB:
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:
318 case GL_RGB_SCALE:
319 case GL_ALPHA_SCALE:
320 break;
321
322 case GL_TEXTURE_LOD_BIAS: {
323 int b = (int) ((*param) * 16.0);
324 if (b > 63) b = 63;
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);
330 break;
331 }
332
333 default:
334 break;
335 }
336 }
337
338 static void i830BindTexture( GLcontext *ctx, GLenum target,
339 struct gl_texture_object *texObj )
340 {
341 i830TextureObjectPtr tex;
342
343 if (!texObj->DriverData)
344 i830AllocTexObj( texObj );
345
346 tex = (i830TextureObjectPtr)texObj->DriverData;
347 }
348
349
350
351 void i830InitTextureFuncs( struct dd_function_table *functions )
352 {
353 functions->BindTexture = i830BindTexture;
354 functions->TexEnv = i830TexEnv;
355 functions->TexParameter = i830TexParameter;
356 }