Revert "intel: Make RGB renderbuffers use XRGB8888 like we do for RGB system buffers."
[mesa.git] / src / mesa / drivers / dri / gamma / gamma_tex.c
1
2 #include "main/glheader.h"
3 #include "main/mtypes.h"
4 #include "main/colormac.h"
5 #include "main/imports.h"
6 #include "main/simple_list.h"
7 #include "main/enums.h"
8 #include "main/mm.h"
9 #include "main/texstore.h"
10 #include "main/teximage.h"
11 #include "main/texobj.h"
12
13 #include "swrast/swrast.h"
14
15 #include "gammacontext.h"
16
17
18 /*
19 * Compute the 'S2.4' lod bias factor from the floating point OpenGL bias.
20 */
21 #if 0
22 static GLuint gammaComputeLodBias(GLfloat bias)
23 {
24 return bias;
25 }
26 #endif
27
28 static void gammaSetTexWrapping(gammaTextureObjectPtr t,
29 GLenum wraps, GLenum wrapt)
30 {
31 uint32_t t1 = t->TextureAddressMode;
32 uint32_t t2 = t->TextureReadMode;
33
34 t1 &= ~(TAM_SWrap_Mask | TAM_TWrap_Mask);
35 t2 &= ~(TRM_UWrap_Mask | TRM_VWrap_Mask);
36
37 if (wraps != GL_CLAMP) {
38 t1 |= TAM_SWrap_Repeat;
39 t2 |= TRM_UWrap_Repeat;
40 }
41
42 if (wrapt != GL_CLAMP) {
43 t1 |= TAM_TWrap_Repeat;
44 t2 |= TRM_VWrap_Repeat;
45 }
46
47 t->TextureAddressMode = t1;
48 t->TextureReadMode = t2;
49 }
50
51
52 static void gammaSetTexFilter(gammaContextPtr gmesa,
53 gammaTextureObjectPtr t,
54 GLenum minf, GLenum magf,
55 GLfloat bias)
56 {
57 uint32_t t1 = t->TextureAddressMode;
58 uint32_t t2 = t->TextureReadMode;
59
60 t2 &= ~(TRM_Mag_Mask | TRM_Min_Mask);
61
62 switch (minf) {
63 case GL_NEAREST:
64 t1 &= ~TAM_LODEnable;
65 t2 &= ~TRM_MipMapEnable;
66 t2 |= TRM_Min_Nearest;
67 break;
68 case GL_LINEAR:
69 t1 &= ~TAM_LODEnable;
70 t2 &= ~TRM_MipMapEnable;
71 t2 |= TRM_Min_Linear;
72 break;
73 case GL_NEAREST_MIPMAP_NEAREST:
74 t2 |= TRM_Min_NearestMMNearest;
75 break;
76 case GL_LINEAR_MIPMAP_NEAREST:
77 t2 |= TRM_Min_LinearMMNearest;
78 break;
79 case GL_NEAREST_MIPMAP_LINEAR:
80 t2 |= TRM_Min_NearestMMLinear;
81 break;
82 case GL_LINEAR_MIPMAP_LINEAR:
83 t2 |= TRM_Min_LinearMMLinear;
84 break;
85 default:
86 break;
87 }
88
89 switch (magf) {
90 case GL_NEAREST:
91 t2 |= TRM_Mag_Nearest;
92 break;
93 case GL_LINEAR:
94 t2 |= TRM_Mag_Linear;
95 break;
96 default:
97 break;
98 }
99
100 t->TextureAddressMode = t1;
101 t->TextureReadMode = t2;
102 }
103
104
105 static void gammaSetTexBorderColor(gammaContextPtr gmesa,
106 gammaTextureObjectPtr t,
107 const GLfloat color[4])
108 {
109 GLubyte c[4];
110 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
111 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
112 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
113 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
114 t->TextureBorderColor = PACK_COLOR_8888(c[0], c[1], c[2], c[3]);
115 }
116
117
118 static void gammaTexParameter( GLcontext *ctx, GLenum target,
119 struct gl_texture_object *tObj,
120 GLenum pname, const GLfloat *params )
121 {
122 gammaContextPtr gmesa = GAMMA_CONTEXT(ctx);
123 gammaTextureObjectPtr t = (gammaTextureObjectPtr) tObj->DriverData;
124 if (!t)
125 return;
126
127 /* Can't do the update now as we don't know whether to flush
128 * vertices or not. Setting gmesa->new_state means that
129 * gammaUpdateTextureState() will be called before any triangles are
130 * rendered. If a statechange has occurred, it will be detected at
131 * that point, and buffered vertices flushed.
132 */
133 switch (pname) {
134 case GL_TEXTURE_MIN_FILTER:
135 case GL_TEXTURE_MAG_FILTER:
136 {
137 GLfloat bias = ctx->Texture.Unit[ctx->Texture.CurrentUnit].LodBias;
138 gammaSetTexFilter( gmesa, t, tObj->MinFilter, tObj->MagFilter, bias );
139 }
140 break;
141
142 case GL_TEXTURE_WRAP_S:
143 case GL_TEXTURE_WRAP_T:
144 gammaSetTexWrapping( t, tObj->WrapS, tObj->WrapT );
145 break;
146
147 case GL_TEXTURE_BORDER_COLOR:
148 gammaSetTexBorderColor( gmesa, t, tObj->BorderColor );
149 break;
150
151 case GL_TEXTURE_BASE_LEVEL:
152 case GL_TEXTURE_MAX_LEVEL:
153 case GL_TEXTURE_MIN_LOD:
154 case GL_TEXTURE_MAX_LOD:
155 /* This isn't the most efficient solution but there doesn't appear to
156 * be a nice alternative for Radeon. Since there's no LOD clamping,
157 * we just have to rely on loading the right subset of mipmap levels
158 * to simulate a clamped LOD.
159 */
160 gammaSwapOutTexObj( gmesa, t );
161 break;
162
163 default:
164 return;
165 }
166
167 if (t == gmesa->CurrentTexObj[0])
168 gmesa->dirty |= GAMMA_UPLOAD_TEX0;
169
170 #if 0
171 if (t == gmesa->CurrentTexObj[1]) {
172 gmesa->dirty |= GAMMA_UPLOAD_TEX1;
173 }
174 #endif
175 }
176
177
178 static void gammaTexEnv( GLcontext *ctx, GLenum target,
179 GLenum pname, const GLfloat *param )
180 {
181 gammaContextPtr gmesa = GAMMA_CONTEXT( ctx );
182 GLuint unit = ctx->Texture.CurrentUnit;
183
184 /* Only one env color. Need a fallback if env colors are different
185 * and texture setup references env color in both units.
186 */
187 switch (pname) {
188 case GL_TEXTURE_ENV_COLOR: {
189 struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
190 GLfloat *fc = texUnit->EnvColor;
191 GLuint r, g, b, a, col;
192 CLAMPED_FLOAT_TO_UBYTE(r, fc[0]);
193 CLAMPED_FLOAT_TO_UBYTE(g, fc[1]);
194 CLAMPED_FLOAT_TO_UBYTE(b, fc[2]);
195 CLAMPED_FLOAT_TO_UBYTE(a, fc[3]);
196
197 col = ((a << 24) |
198 (r << 16) |
199 (g << 8) |
200 (b << 0));
201
202 break;
203 }
204 case GL_TEXTURE_ENV_MODE:
205 gmesa->TexEnvImageFmt[unit] = 0; /* force recalc of env state */
206 break;
207
208 case GL_TEXTURE_LOD_BIAS_EXT:
209 #if 0 /* ?!?!?! */
210 {
211 struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
212 gammaTextureObjectPtr t = (gammaTextureObjectPtr) tObj->DriverData;
213 (void) t;
214 /* XXX Looks like there's something missing here */
215 }
216 #endif
217 break;
218
219 default:
220 break;
221 }
222 }
223
224 #if 0
225 static void gammaTexImage1D( GLcontext *ctx, GLenum target, GLint level,
226 GLint internalFormat,
227 GLint width, GLint border,
228 GLenum format, GLenum type,
229 const GLvoid *pixels,
230 const struct gl_pixelstore_attrib *pack,
231 struct gl_texture_object *texObj,
232 struct gl_texture_image *texImage )
233 {
234 gammaTextureObjectPtr t = (gammaTextureObjectPtr) texObj->DriverData;
235 if (t) {
236 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx), t );
237 }
238 _mesa_store_teximage1d( ctx, target, level, internalFormat,
239 width, border, format, type,
240 pixels, pack, texObj, texImage );
241 }
242 #endif
243
244 #if 0
245 static void gammaTexSubImage1D( GLcontext *ctx,
246 GLenum target,
247 GLint level,
248 GLint xoffset,
249 GLsizei width,
250 GLenum format, GLenum type,
251 const GLvoid *pixels,
252 const struct gl_pixelstore_attrib *pack,
253 struct gl_texture_object *texObj,
254 struct gl_texture_image *texImage )
255 {
256 gammaTextureObjectPtr t = (gammaTextureObjectPtr) texObj->DriverData;
257 if (t) {
258 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx), t );
259 }
260 _mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
261 format, type, pixels, pack, texObj,
262 texImage);
263 }
264 #endif
265
266 static void gammaTexImage2D( GLcontext *ctx, GLenum target, GLint level,
267 GLint internalFormat,
268 GLint width, GLint height, GLint border,
269 GLenum format, GLenum type, const GLvoid *pixels,
270 const struct gl_pixelstore_attrib *packing,
271 struct gl_texture_object *texObj,
272 struct gl_texture_image *texImage )
273 {
274 gammaTextureObjectPtr t = (gammaTextureObjectPtr) texObj->DriverData;
275 if (t) {
276 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx), t );
277 }
278 _mesa_store_teximage2d( ctx, target, level, internalFormat,
279 width, height, border, format, type,
280 pixels, packing, texObj, texImage );
281 }
282
283 static void gammaTexSubImage2D( GLcontext *ctx,
284 GLenum target,
285 GLint level,
286 GLint xoffset, GLint yoffset,
287 GLsizei width, GLsizei height,
288 GLenum format, GLenum type,
289 const GLvoid *pixels,
290 const struct gl_pixelstore_attrib *packing,
291 struct gl_texture_object *texObj,
292 struct gl_texture_image *texImage )
293 {
294 gammaTextureObjectPtr t = (gammaTextureObjectPtr) texObj->DriverData;
295 if (t) {
296 gammaSwapOutTexObj( GAMMA_CONTEXT(ctx), t );
297 }
298 _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
299 height, format, type, pixels, packing, texObj,
300 texImage);
301 }
302
303 static void gammaBindTexture( GLcontext *ctx, GLenum target,
304 struct gl_texture_object *tObj )
305 {
306 gammaContextPtr gmesa = GAMMA_CONTEXT( ctx );
307 gammaTextureObjectPtr t = (gammaTextureObjectPtr) tObj->DriverData;
308
309 if (!t) {
310 GLfloat bias = ctx->Texture.Unit[ctx->Texture.CurrentUnit].LodBias;
311 t = CALLOC_STRUCT(gamma_texture_object_t);
312
313 /* Initialize non-image-dependent parts of the state:
314 */
315 t->globj = tObj;
316
317 t->TextureAddressMode = TextureAddressModeEnable | TAM_Operation_3D |
318 TAM_DY_Enable | TAM_LODEnable;
319 t->TextureReadMode = TextureReadModeEnable | TRM_PrimaryCacheEnable |
320 TRM_MipMapEnable | TRM_BorderClamp | TRM_Border;
321 t->TextureColorMode = TextureColorModeEnable;
322 t->TextureFilterMode = TextureFilterModeEnable;
323
324 if (target == GL_TEXTURE_2D) {
325 t->TextureAddressMode |= TAM_TexMapType_2D;
326 t->TextureReadMode |= TRM_TexMapType_2D;
327 }
328 else if (target == GL_TEXTURE_1D) {
329 t->TextureAddressMode |= TAM_TexMapType_1D;
330 t->TextureReadMode |= TRM_TexMapType_1D;
331 }
332
333 t->TextureColorMode = TextureColorModeEnable;
334
335 t->TextureFilterMode = TextureFilterModeEnable;
336
337 #ifdef MESA_LITTLE_ENDIAN
338 t->TextureFormat = (TF_LittleEndian |
339 #else
340 t->TextureFormat = (TF_BigEndian |
341 #endif
342 TF_ColorOrder_RGB |
343 TF_OutputFmt_Texel);
344
345 t->dirty_images = ~0;
346
347 tObj->DriverData = t;
348 make_empty_list( t );
349
350 gammaSetTexWrapping( t, tObj->WrapS, tObj->WrapT );
351 gammaSetTexFilter( gmesa, t, tObj->MinFilter, tObj->MagFilter, bias );
352 gammaSetTexBorderColor( gmesa, t, tObj->BorderColor );
353 }
354 }
355
356 static void gammaDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
357 {
358 gammaTextureObjectPtr t = (gammaTextureObjectPtr)tObj->DriverData;
359
360 if (t) {
361 gammaContextPtr gmesa = GAMMA_CONTEXT( ctx );
362 #if 0
363 if (gmesa)
364 GAMMA_FIREVERTICES( gmesa );
365 #endif
366 gammaDestroyTexObj( gmesa, t );
367 tObj->DriverData = 0;
368 }
369 /* Free mipmap images and the texture object itself */
370 _mesa_delete_texture_object(ctx, tObj);
371 }
372
373 static GLboolean gammaIsTextureResident( GLcontext *ctx,
374 struct gl_texture_object *tObj )
375 {
376 gammaTextureObjectPtr t = (gammaTextureObjectPtr)tObj->DriverData;
377 return t && t->MemBlock;
378 }
379
380 #ifdef UNUSED
381 /**
382 * Allocate a new texture object.
383 * Called via ctx->Driver.NewTextureObject.
384 * Note: this function will be called during context creation to
385 * allocate the default texture objects.
386 * Note: we could use containment here to 'derive' the driver-specific
387 * texture object from the core mesa gl_texture_object. Not done at this time.
388 */
389 static struct gl_texture_object *
390 gammaNewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
391 {
392 struct gl_texture_object *obj;
393 obj = _mesa_new_texture_object(ctx, name, target);
394 return obj;
395 }
396 #endif
397
398 void gammaInitTextureObjects( GLcontext *ctx )
399 {
400 struct gl_texture_object *texObj;
401 GLuint tmp = ctx->Texture.CurrentUnit;
402
403 ctx->Texture.CurrentUnit = 0;
404
405 texObj = ctx->Texture.Unit[0].CurrentTex[TEXTURE_1D_INDEX];
406 gammaBindTexture( ctx, GL_TEXTURE_1D, texObj );
407
408 texObj = ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX];
409 gammaBindTexture( ctx, GL_TEXTURE_2D, texObj );
410
411 #if 0
412 ctx->Texture.CurrentUnit = 1;
413
414 texObj = ctx->Texture.Unit[1].CurrentTex[TEXTURE_1D_INDEX];
415 gammaBindTexture( ctx, GL_TEXTURE_1D, texObj );
416
417 texObj = ctx->Texture.Unit[1].CurrentTex[TEXTURE_2D_INDEX];
418 gammaBindTexture( ctx, GL_TEXTURE_2D, texObj );
419 #endif
420
421 ctx->Texture.CurrentUnit = tmp;
422 }
423
424
425 void gammaDDInitTextureFuncs( struct dd_function_table *functions )
426 {
427 functions->TexEnv = gammaTexEnv;
428 functions->TexImage2D = gammaTexImage2D;
429 functions->TexSubImage2D = gammaTexSubImage2D;
430 functions->BindTexture = gammaBindTexture;
431 functions->DeleteTexture = gammaDeleteTexture;
432 functions->TexParameter = gammaTexParameter;
433 functions->IsTextureResident = gammaIsTextureResident;
434 }