Merge commit 'origin/openvg-1.0'
[mesa.git] / src / mesa / main / texparam.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.5
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions 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 MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 /**
27 * \file texparam.c
28 *
29 * glTexParameter-related functions
30 */
31
32
33 #include "main/glheader.h"
34 #include "main/context.h"
35 #include "main/enums.h"
36 #include "main/colormac.h"
37 #include "main/macros.h"
38 #include "main/texcompress.h"
39 #include "main/texparam.h"
40 #include "main/teximage.h"
41 #include "shader/prog_instruction.h"
42
43
44 /**
45 * Check if a coordinate wrap mode is supported for the texture target.
46 * \return GL_TRUE if legal, GL_FALSE otherwise
47 */
48 static GLboolean
49 validate_texture_wrap_mode(GLcontext * ctx, GLenum target, GLenum wrap)
50 {
51 const struct gl_extensions * const e = & ctx->Extensions;
52
53 if (wrap == GL_CLAMP || wrap == GL_CLAMP_TO_EDGE ||
54 (wrap == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
55 /* any texture target */
56 return GL_TRUE;
57 }
58 else if (target != GL_TEXTURE_RECTANGLE_NV &&
59 (wrap == GL_REPEAT ||
60 (wrap == GL_MIRRORED_REPEAT &&
61 e->ARB_texture_mirrored_repeat) ||
62 (wrap == GL_MIRROR_CLAMP_EXT &&
63 (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
64 (wrap == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
65 (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
66 (wrap == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
67 (e->EXT_texture_mirror_clamp)))) {
68 /* non-rectangle texture */
69 return GL_TRUE;
70 }
71
72 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)", wrap );
73 return GL_FALSE;
74 }
75
76
77 /**
78 * Get current texture object for given target.
79 * Return NULL if any error.
80 */
81 static struct gl_texture_object *
82 get_texobj(GLcontext *ctx, GLenum target)
83 {
84 struct gl_texture_unit *texUnit;
85
86 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
87 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(current unit)");
88 return NULL;
89 }
90
91 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
92
93 switch (target) {
94 case GL_TEXTURE_1D:
95 return texUnit->CurrentTex[TEXTURE_1D_INDEX];
96 case GL_TEXTURE_2D:
97 return texUnit->CurrentTex[TEXTURE_2D_INDEX];
98 case GL_TEXTURE_3D:
99 return texUnit->CurrentTex[TEXTURE_3D_INDEX];
100 case GL_TEXTURE_CUBE_MAP:
101 if (ctx->Extensions.ARB_texture_cube_map) {
102 return texUnit->CurrentTex[TEXTURE_CUBE_INDEX];
103 }
104 break;
105 case GL_TEXTURE_RECTANGLE_NV:
106 if (ctx->Extensions.NV_texture_rectangle) {
107 return texUnit->CurrentTex[TEXTURE_RECT_INDEX];
108 }
109 break;
110 case GL_TEXTURE_1D_ARRAY_EXT:
111 if (ctx->Extensions.MESA_texture_array) {
112 return texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX];
113 }
114 break;
115 case GL_TEXTURE_2D_ARRAY_EXT:
116 if (ctx->Extensions.MESA_texture_array) {
117 return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX];
118 }
119 break;
120 default:
121 ;
122 }
123
124 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(target)");
125 return NULL;
126 }
127
128
129 /**
130 * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE.
131 * \return -1 if error.
132 */
133 static GLint
134 comp_to_swizzle(GLenum comp)
135 {
136 switch (comp) {
137 case GL_RED:
138 return SWIZZLE_X;
139 case GL_GREEN:
140 return SWIZZLE_Y;
141 case GL_BLUE:
142 return SWIZZLE_Z;
143 case GL_ALPHA:
144 return SWIZZLE_W;
145 case GL_ZERO:
146 return SWIZZLE_ZERO;
147 case GL_ONE:
148 return SWIZZLE_ONE;
149 default:
150 return -1;
151 }
152 }
153
154
155 static void
156 set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz)
157 {
158 ASSERT(comp < 4);
159 ASSERT(swz <= SWIZZLE_NIL);
160 {
161 GLuint mask = 0x7 << (3 * comp);
162 GLuint s = (*swizzle & ~mask) | (swz << (3 * comp));
163 *swizzle = s;
164 }
165 }
166
167
168 /**
169 * This is called just prior to changing any texture object state.
170 * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE
171 * state flag and then mark the texture object as 'incomplete' so that any
172 * per-texture derived state gets recomputed.
173 */
174 static INLINE void
175 flush(GLcontext *ctx, struct gl_texture_object *texObj)
176 {
177 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
178 texObj->_Complete = GL_FALSE;
179 }
180
181
182 /**
183 * Set an integer-valued texture parameter
184 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
185 */
186 static GLboolean
187 set_tex_parameteri(GLcontext *ctx,
188 struct gl_texture_object *texObj,
189 GLenum pname, const GLint *params)
190 {
191 switch (pname) {
192 case GL_TEXTURE_MIN_FILTER:
193 if (texObj->MinFilter == params[0])
194 return GL_FALSE;
195 switch (params[0]) {
196 case GL_NEAREST:
197 case GL_LINEAR:
198 flush(ctx, texObj);
199 texObj->MinFilter = params[0];
200 return GL_TRUE;
201 case GL_NEAREST_MIPMAP_NEAREST:
202 case GL_LINEAR_MIPMAP_NEAREST:
203 case GL_NEAREST_MIPMAP_LINEAR:
204 case GL_LINEAR_MIPMAP_LINEAR:
205 if (texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
206 flush(ctx, texObj);
207 texObj->MinFilter = params[0];
208 return GL_TRUE;
209 }
210 /* fall-through */
211 default:
212 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)",
213 params[0] );
214 }
215 return GL_FALSE;
216
217 case GL_TEXTURE_MAG_FILTER:
218 if (texObj->MagFilter == params[0])
219 return GL_FALSE;
220 switch (params[0]) {
221 case GL_NEAREST:
222 case GL_LINEAR:
223 flush(ctx, texObj);
224 texObj->MagFilter = params[0];
225 return GL_TRUE;
226 default:
227 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)",
228 params[0]);
229 }
230 return GL_FALSE;
231
232 case GL_TEXTURE_WRAP_S:
233 if (texObj->WrapS == params[0])
234 return GL_FALSE;
235 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
236 flush(ctx, texObj);
237 texObj->WrapS = params[0];
238 return GL_TRUE;
239 }
240 return GL_FALSE;
241
242 case GL_TEXTURE_WRAP_T:
243 if (texObj->WrapT == params[0])
244 return GL_FALSE;
245 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
246 flush(ctx, texObj);
247 texObj->WrapT = params[0];
248 return GL_TRUE;
249 }
250 return GL_FALSE;
251
252 case GL_TEXTURE_WRAP_R:
253 if (texObj->WrapR == params[0])
254 return GL_FALSE;
255 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
256 flush(ctx, texObj);
257 texObj->WrapR = params[0];
258 return GL_TRUE;
259 }
260 return GL_FALSE;
261
262 case GL_TEXTURE_BASE_LEVEL:
263 if (texObj->BaseLevel == params[0])
264 return GL_FALSE;
265 if (params[0] < 0 ||
266 (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) {
267 _mesa_error(ctx, GL_INVALID_VALUE,
268 "glTexParameter(param=%d)", params[0]);
269 return GL_FALSE;
270 }
271 flush(ctx, texObj);
272 texObj->BaseLevel = params[0];
273 return GL_TRUE;
274
275 case GL_TEXTURE_MAX_LEVEL:
276 if (texObj->MaxLevel == params[0])
277 return GL_FALSE;
278 if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) {
279 _mesa_error(ctx, GL_INVALID_OPERATION,
280 "glTexParameter(param=%d)", params[0]);
281 return GL_FALSE;
282 }
283 flush(ctx, texObj);
284 texObj->MaxLevel = params[0];
285 return GL_TRUE;
286
287 case GL_GENERATE_MIPMAP_SGIS:
288 if (ctx->Extensions.SGIS_generate_mipmap) {
289 if (texObj->GenerateMipmap != params[0]) {
290 flush(ctx, texObj);
291 texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
292 return GL_TRUE;
293 }
294 return GL_FALSE;
295 }
296 else {
297 _mesa_error(ctx, GL_INVALID_ENUM,
298 "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)");
299 }
300 return GL_FALSE;
301
302 case GL_TEXTURE_COMPARE_MODE_ARB:
303 if (ctx->Extensions.ARB_shadow &&
304 (params[0] == GL_NONE ||
305 params[0] == GL_COMPARE_R_TO_TEXTURE_ARB)) {
306 if (texObj->CompareMode != params[0]) {
307 flush(ctx, texObj);
308 texObj->CompareMode = params[0];
309 return GL_TRUE;
310 }
311 return GL_FALSE;
312 }
313 else {
314 _mesa_error(ctx, GL_INVALID_ENUM,
315 "glTexParameter(GL_TEXTURE_COMPARE_MODE_ARB)");
316 }
317 return GL_FALSE;
318
319 case GL_TEXTURE_COMPARE_FUNC_ARB:
320 if (ctx->Extensions.ARB_shadow) {
321 if (texObj->CompareFunc == params[0])
322 return GL_FALSE;
323 switch (params[0]) {
324 case GL_LEQUAL:
325 case GL_GEQUAL:
326 flush(ctx, texObj);
327 texObj->CompareFunc = params[0];
328 return GL_TRUE;
329 case GL_EQUAL:
330 case GL_NOTEQUAL:
331 case GL_LESS:
332 case GL_GREATER:
333 case GL_ALWAYS:
334 case GL_NEVER:
335 if (ctx->Extensions.EXT_shadow_funcs) {
336 flush(ctx, texObj);
337 texObj->CompareFunc = params[0];
338 return GL_TRUE;
339 }
340 /* fall-through */
341 default:
342 _mesa_error(ctx, GL_INVALID_ENUM,
343 "glTexParameter(GL_TEXTURE_COMPARE_FUNC_ARB)");
344 }
345 }
346 else {
347 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
348 }
349 return GL_FALSE;
350
351 case GL_DEPTH_TEXTURE_MODE_ARB:
352 if (ctx->Extensions.ARB_depth_texture &&
353 (params[0] == GL_LUMINANCE ||
354 params[0] == GL_INTENSITY ||
355 params[0] == GL_ALPHA)) {
356 if (texObj->DepthMode != params[0]) {
357 flush(ctx, texObj);
358 texObj->DepthMode = params[0];
359 return GL_TRUE;
360 }
361 }
362 else {
363 _mesa_error(ctx, GL_INVALID_ENUM,
364 "glTexParameter(GL_DEPTH_TEXTURE_MODE_ARB)");
365 }
366 return GL_FALSE;
367
368 #ifdef FEATURE_OES_draw_texture
369 case GL_TEXTURE_CROP_RECT_OES:
370 texObj->CropRect[0] = params[0];
371 texObj->CropRect[1] = params[1];
372 texObj->CropRect[2] = params[2];
373 texObj->CropRect[3] = params[3];
374 return GL_TRUE;
375 #endif
376
377 case GL_TEXTURE_SWIZZLE_R_EXT:
378 case GL_TEXTURE_SWIZZLE_G_EXT:
379 case GL_TEXTURE_SWIZZLE_B_EXT:
380 case GL_TEXTURE_SWIZZLE_A_EXT:
381 if (ctx->Extensions.EXT_texture_swizzle) {
382 const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
383 const GLint swz = comp_to_swizzle(params[0]);
384 if (swz < 0) {
385 _mesa_error(ctx, GL_INVALID_OPERATION,
386 "glTexParameter(swizzle 0x%x)", params[0]);
387 return GL_FALSE;
388 }
389 ASSERT(comp < 4);
390 if (swz >= 0) {
391 flush(ctx, texObj);
392 texObj->Swizzle[comp] = params[0];
393 set_swizzle_component(&texObj->_Swizzle, comp, swz);
394 return GL_TRUE;
395 }
396 }
397 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
398 return GL_FALSE;
399
400 case GL_TEXTURE_SWIZZLE_RGBA_EXT:
401 if (ctx->Extensions.EXT_texture_swizzle) {
402 GLuint comp;
403 flush(ctx, texObj);
404 for (comp = 0; comp < 4; comp++) {
405 const GLint swz = comp_to_swizzle(params[comp]);
406 if (swz >= 0) {
407 texObj->Swizzle[comp] = params[comp];
408 set_swizzle_component(&texObj->_Swizzle, comp, swz);
409 }
410 else {
411 _mesa_error(ctx, GL_INVALID_OPERATION,
412 "glTexParameter(swizzle 0x%x)", params[comp]);
413 return GL_FALSE;
414 }
415 }
416 return GL_TRUE;
417 }
418 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
419 return GL_FALSE;
420
421 default:
422 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
423 }
424 return GL_FALSE;
425 }
426
427
428 /**
429 * Set a float-valued texture parameter
430 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
431 */
432 static GLboolean
433 set_tex_parameterf(GLcontext *ctx,
434 struct gl_texture_object *texObj,
435 GLenum pname, const GLfloat *params)
436 {
437 switch (pname) {
438 case GL_TEXTURE_MIN_LOD:
439 if (texObj->MinLod == params[0])
440 return GL_FALSE;
441 flush(ctx, texObj);
442 texObj->MinLod = params[0];
443 return GL_TRUE;
444
445 case GL_TEXTURE_MAX_LOD:
446 if (texObj->MaxLod == params[0])
447 return GL_FALSE;
448 flush(ctx, texObj);
449 texObj->MaxLod = params[0];
450 return GL_TRUE;
451
452 case GL_TEXTURE_PRIORITY:
453 flush(ctx, texObj);
454 texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
455 return GL_TRUE;
456
457 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
458 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
459 if (texObj->MaxAnisotropy == params[0])
460 return GL_FALSE;
461 if (params[0] < 1.0) {
462 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
463 return GL_FALSE;
464 }
465 flush(ctx, texObj);
466 /* clamp to max, that's what NVIDIA does */
467 texObj->MaxAnisotropy = MIN2(params[0],
468 ctx->Const.MaxTextureMaxAnisotropy);
469 return GL_TRUE;
470 }
471 else {
472 static GLuint count = 0;
473 if (count++ < 10)
474 _mesa_error(ctx, GL_INVALID_ENUM,
475 "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
476 }
477 return GL_FALSE;
478
479 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
480 if (ctx->Extensions.ARB_shadow_ambient) {
481 if (texObj->CompareFailValue != params[0]) {
482 flush(ctx, texObj);
483 texObj->CompareFailValue = CLAMP(params[0], 0.0F, 1.0F);
484 return GL_TRUE;
485 }
486 }
487 else {
488 _mesa_error(ctx, GL_INVALID_ENUM,
489 "glTexParameter(pname=GL_TEXTURE_COMPARE_FAIL_VALUE_ARB)");
490 }
491 return GL_FALSE;
492
493 case GL_TEXTURE_LOD_BIAS:
494 /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias */
495 if (ctx->Extensions.EXT_texture_lod_bias) {
496 if (texObj->LodBias != params[0]) {
497 flush(ctx, texObj);
498 texObj->LodBias = params[0];
499 return GL_TRUE;
500 }
501 return GL_FALSE;
502 }
503 break;
504
505 case GL_TEXTURE_BORDER_COLOR:
506 flush(ctx, texObj);
507 texObj->BorderColor[RCOMP] = params[0];
508 texObj->BorderColor[GCOMP] = params[1];
509 texObj->BorderColor[BCOMP] = params[2];
510 texObj->BorderColor[ACOMP] = params[3];
511 return GL_TRUE;
512
513 default:
514 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
515 }
516 return GL_FALSE;
517 }
518
519
520 void GLAPIENTRY
521 _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
522 {
523 GLboolean need_update;
524 struct gl_texture_object *texObj;
525 GET_CURRENT_CONTEXT(ctx);
526 ASSERT_OUTSIDE_BEGIN_END(ctx);
527
528 texObj = get_texobj(ctx, target);
529 if (!texObj)
530 return;
531
532 switch (pname) {
533 case GL_TEXTURE_MIN_FILTER:
534 case GL_TEXTURE_MAG_FILTER:
535 case GL_TEXTURE_WRAP_S:
536 case GL_TEXTURE_WRAP_T:
537 case GL_TEXTURE_WRAP_R:
538 case GL_TEXTURE_BASE_LEVEL:
539 case GL_TEXTURE_MAX_LEVEL:
540 case GL_GENERATE_MIPMAP_SGIS:
541 case GL_TEXTURE_COMPARE_MODE_ARB:
542 case GL_TEXTURE_COMPARE_FUNC_ARB:
543 case GL_DEPTH_TEXTURE_MODE_ARB:
544 {
545 /* convert float param to int */
546 GLint p = (GLint) param;
547 need_update = set_tex_parameteri(ctx, texObj, pname, &p);
548 }
549 break;
550 default:
551 /* this will generate an error if pname is illegal */
552 need_update = set_tex_parameterf(ctx, texObj, pname, &param);
553 }
554
555 if (ctx->Driver.TexParameter && need_update) {
556 ctx->Driver.TexParameter(ctx, target, texObj, pname, &param);
557 }
558 }
559
560
561 void GLAPIENTRY
562 _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
563 {
564 GLboolean need_update;
565 struct gl_texture_object *texObj;
566 GET_CURRENT_CONTEXT(ctx);
567 ASSERT_OUTSIDE_BEGIN_END(ctx);
568
569 texObj = get_texobj(ctx, target);
570 if (!texObj)
571 return;
572
573 switch (pname) {
574 case GL_TEXTURE_MIN_FILTER:
575 case GL_TEXTURE_MAG_FILTER:
576 case GL_TEXTURE_WRAP_S:
577 case GL_TEXTURE_WRAP_T:
578 case GL_TEXTURE_WRAP_R:
579 case GL_TEXTURE_BASE_LEVEL:
580 case GL_TEXTURE_MAX_LEVEL:
581 case GL_GENERATE_MIPMAP_SGIS:
582 case GL_TEXTURE_COMPARE_MODE_ARB:
583 case GL_TEXTURE_COMPARE_FUNC_ARB:
584 case GL_DEPTH_TEXTURE_MODE_ARB:
585 {
586 /* convert float param to int */
587 GLint p = (GLint) params[0];
588 need_update = set_tex_parameteri(ctx, texObj, pname, &p);
589 }
590 break;
591
592 #ifdef FEATURE_OES_draw_texture
593 case GL_TEXTURE_CROP_RECT_OES:
594 {
595 /* convert float params to int */
596 GLint iparams[4];
597 iparams[0] = (GLint) params[0];
598 iparams[1] = (GLint) params[1];
599 iparams[2] = (GLint) params[2];
600 iparams[3] = (GLint) params[3];
601 need_update = set_tex_parameteri(ctx, target, iparams);
602 }
603 break;
604 #endif
605
606 default:
607 /* this will generate an error if pname is illegal */
608 need_update = set_tex_parameterf(ctx, texObj, pname, params);
609 }
610
611 if (ctx->Driver.TexParameter && need_update) {
612 ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
613 }
614 }
615
616
617 void GLAPIENTRY
618 _mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
619 {
620 GLboolean need_update;
621 struct gl_texture_object *texObj;
622 GET_CURRENT_CONTEXT(ctx);
623 ASSERT_OUTSIDE_BEGIN_END(ctx);
624
625 texObj = get_texobj(ctx, target);
626 if (!texObj)
627 return;
628
629 switch (pname) {
630 case GL_TEXTURE_MIN_LOD:
631 case GL_TEXTURE_MAX_LOD:
632 case GL_TEXTURE_PRIORITY:
633 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
634 case GL_TEXTURE_LOD_BIAS:
635 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
636 {
637 GLfloat fparam = (GLfloat) param;
638 /* convert int param to float */
639 need_update = set_tex_parameterf(ctx, texObj, pname, &fparam);
640 }
641 break;
642 default:
643 /* this will generate an error if pname is illegal */
644 need_update = set_tex_parameteri(ctx, texObj, pname, &param);
645 }
646
647 if (ctx->Driver.TexParameter && need_update) {
648 GLfloat fparam = (GLfloat) param;
649 ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam);
650 }
651 }
652
653
654 void GLAPIENTRY
655 _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
656 {
657 GLboolean need_update;
658 struct gl_texture_object *texObj;
659 GET_CURRENT_CONTEXT(ctx);
660 ASSERT_OUTSIDE_BEGIN_END(ctx);
661
662 texObj = get_texobj(ctx, target);
663 if (!texObj)
664 return;
665
666 switch (pname) {
667 case GL_TEXTURE_BORDER_COLOR:
668 {
669 /* convert int params to float */
670 GLfloat fparams[4];
671 fparams[0] = INT_TO_FLOAT(params[0]);
672 fparams[1] = INT_TO_FLOAT(params[1]);
673 fparams[2] = INT_TO_FLOAT(params[2]);
674 fparams[3] = INT_TO_FLOAT(params[3]);
675 need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
676 }
677 break;
678 case GL_TEXTURE_MIN_LOD:
679 case GL_TEXTURE_MAX_LOD:
680 case GL_TEXTURE_PRIORITY:
681 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
682 case GL_TEXTURE_LOD_BIAS:
683 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
684 {
685 /* convert int param to float */
686 GLfloat fparam = (GLfloat) params[0];
687 need_update = set_tex_parameterf(ctx, texObj, pname, &fparam);
688 }
689 break;
690 default:
691 /* this will generate an error if pname is illegal */
692 need_update = set_tex_parameteri(ctx, texObj, pname, params);
693 }
694
695 if (ctx->Driver.TexParameter && need_update) {
696 GLfloat fparams[4];
697 fparams[0] = INT_TO_FLOAT(params[0]);
698 if (pname == GL_TEXTURE_BORDER_COLOR ||
699 pname == GL_TEXTURE_CROP_RECT_OES) {
700 fparams[1] = INT_TO_FLOAT(params[1]);
701 fparams[2] = INT_TO_FLOAT(params[2]);
702 fparams[3] = INT_TO_FLOAT(params[3]);
703 }
704 ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams);
705 }
706 }
707
708
709 void GLAPIENTRY
710 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
711 GLenum pname, GLfloat *params )
712 {
713 GLint iparam;
714 _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
715 *params = (GLfloat) iparam;
716 }
717
718
719 static GLuint
720 tex_image_dimensions(GLcontext *ctx, GLenum target)
721 {
722 switch (target) {
723 case GL_TEXTURE_1D:
724 case GL_PROXY_TEXTURE_1D:
725 return 1;
726 case GL_TEXTURE_2D:
727 case GL_PROXY_TEXTURE_2D:
728 return 2;
729 case GL_TEXTURE_3D:
730 case GL_PROXY_TEXTURE_3D:
731 return 3;
732 case GL_TEXTURE_CUBE_MAP:
733 case GL_PROXY_TEXTURE_CUBE_MAP:
734 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
735 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
736 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
737 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
738 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
739 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
740 return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
741 case GL_TEXTURE_RECTANGLE_NV:
742 case GL_PROXY_TEXTURE_RECTANGLE_NV:
743 return ctx->Extensions.NV_texture_rectangle ? 2 : 0;
744 case GL_TEXTURE_1D_ARRAY_EXT:
745 case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
746 return ctx->Extensions.MESA_texture_array ? 2 : 0;
747 case GL_TEXTURE_2D_ARRAY_EXT:
748 case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
749 return ctx->Extensions.MESA_texture_array ? 3 : 0;
750 default:
751 _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
752 return 0;
753 }
754 }
755
756
757 void GLAPIENTRY
758 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
759 GLenum pname, GLint *params )
760 {
761 const struct gl_texture_unit *texUnit;
762 struct gl_texture_object *texObj;
763 const struct gl_texture_image *img = NULL;
764 GLuint dimensions;
765 GLboolean isProxy;
766 GLint maxLevels;
767 GET_CURRENT_CONTEXT(ctx);
768 ASSERT_OUTSIDE_BEGIN_END(ctx);
769
770 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
771 _mesa_error(ctx, GL_INVALID_OPERATION,
772 "glGetTexLevelParameteriv(current unit)");
773 return;
774 }
775
776 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
777
778 /* this will catch bad target values */
779 dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */
780 if (dimensions == 0) {
781 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
782 return;
783 }
784
785 maxLevels = _mesa_max_texture_levels(ctx, target);
786 if (maxLevels == 0) {
787 /* should not happen since <target> was just checked above */
788 _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter");
789 return;
790 }
791
792 if (level < 0 || level >= maxLevels) {
793 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
794 return;
795 }
796
797 texObj = _mesa_select_tex_object(ctx, texUnit, target);
798 _mesa_lock_texture(ctx, texObj);
799
800 img = _mesa_select_tex_image(ctx, texObj, target, level);
801 if (!img || !img->TexFormat) {
802 /* undefined texture image */
803 if (pname == GL_TEXTURE_COMPONENTS)
804 *params = 1;
805 else
806 *params = 0;
807 goto out;
808 }
809
810 isProxy = _mesa_is_proxy_texture(target);
811
812 switch (pname) {
813 case GL_TEXTURE_WIDTH:
814 *params = img->Width;
815 break;
816 case GL_TEXTURE_HEIGHT:
817 *params = img->Height;
818 break;
819 case GL_TEXTURE_DEPTH:
820 *params = img->Depth;
821 break;
822 case GL_TEXTURE_INTERNAL_FORMAT:
823 *params = img->InternalFormat;
824 break;
825 case GL_TEXTURE_BORDER:
826 *params = img->Border;
827 break;
828 case GL_TEXTURE_RED_SIZE:
829 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
830 *params = img->TexFormat->RedBits;
831 else
832 *params = 0;
833 break;
834 case GL_TEXTURE_GREEN_SIZE:
835 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
836 *params = img->TexFormat->GreenBits;
837 else
838 *params = 0;
839 break;
840 case GL_TEXTURE_BLUE_SIZE:
841 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
842 *params = img->TexFormat->BlueBits;
843 else
844 *params = 0;
845 break;
846 case GL_TEXTURE_ALPHA_SIZE:
847 if (img->_BaseFormat == GL_ALPHA ||
848 img->_BaseFormat == GL_LUMINANCE_ALPHA ||
849 img->_BaseFormat == GL_RGBA)
850 *params = img->TexFormat->AlphaBits;
851 else
852 *params = 0;
853 break;
854 case GL_TEXTURE_INTENSITY_SIZE:
855 if (img->_BaseFormat != GL_INTENSITY)
856 *params = 0;
857 else if (img->TexFormat->IntensityBits > 0)
858 *params = img->TexFormat->IntensityBits;
859 else /* intensity probably stored as rgb texture */
860 *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
861 break;
862 case GL_TEXTURE_LUMINANCE_SIZE:
863 if (img->_BaseFormat != GL_LUMINANCE &&
864 img->_BaseFormat != GL_LUMINANCE_ALPHA)
865 *params = 0;
866 else if (img->TexFormat->LuminanceBits > 0)
867 *params = img->TexFormat->LuminanceBits;
868 else /* luminance probably stored as rgb texture */
869 *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
870 break;
871 case GL_TEXTURE_INDEX_SIZE_EXT:
872 if (img->_BaseFormat == GL_COLOR_INDEX)
873 *params = img->TexFormat->IndexBits;
874 else
875 *params = 0;
876 break;
877 case GL_TEXTURE_DEPTH_SIZE_ARB:
878 if (ctx->Extensions.ARB_depth_texture)
879 *params = img->TexFormat->DepthBits;
880 else
881 _mesa_error(ctx, GL_INVALID_ENUM,
882 "glGetTexLevelParameter[if]v(pname)");
883 break;
884 case GL_TEXTURE_STENCIL_SIZE_EXT:
885 if (ctx->Extensions.EXT_packed_depth_stencil ||
886 ctx->Extensions.ARB_framebuffer_object) {
887 *params = img->TexFormat->StencilBits;
888 }
889 else {
890 _mesa_error(ctx, GL_INVALID_ENUM,
891 "glGetTexLevelParameter[if]v(pname)");
892 }
893 break;
894
895 /* GL_ARB_texture_compression */
896 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
897 if (img->IsCompressed && !isProxy) {
898 /* Don't use ctx->Driver.CompressedTextureSize() since that
899 * may returned a padded hardware size.
900 */
901 *params = _mesa_compressed_texture_size(ctx, img->Width,
902 img->Height, img->Depth,
903 img->TexFormat->MesaFormat);
904 }
905 else {
906 _mesa_error(ctx, GL_INVALID_OPERATION,
907 "glGetTexLevelParameter[if]v(pname)");
908 }
909 break;
910 case GL_TEXTURE_COMPRESSED:
911 *params = (GLint) img->IsCompressed;
912 break;
913
914 /* GL_ARB_texture_float */
915 case GL_TEXTURE_RED_TYPE_ARB:
916 if (ctx->Extensions.ARB_texture_float) {
917 *params = img->TexFormat->RedBits ? img->TexFormat->DataType : GL_NONE;
918 }
919 else {
920 _mesa_error(ctx, GL_INVALID_ENUM,
921 "glGetTexLevelParameter[if]v(pname)");
922 }
923 break;
924 case GL_TEXTURE_GREEN_TYPE_ARB:
925 if (ctx->Extensions.ARB_texture_float) {
926 *params = img->TexFormat->GreenBits ? img->TexFormat->DataType : GL_NONE;
927 }
928 else {
929 _mesa_error(ctx, GL_INVALID_ENUM,
930 "glGetTexLevelParameter[if]v(pname)");
931 }
932 break;
933 case GL_TEXTURE_BLUE_TYPE_ARB:
934 if (ctx->Extensions.ARB_texture_float) {
935 *params = img->TexFormat->BlueBits ? img->TexFormat->DataType : GL_NONE;
936 }
937 else {
938 _mesa_error(ctx, GL_INVALID_ENUM,
939 "glGetTexLevelParameter[if]v(pname)");
940 }
941 break;
942 case GL_TEXTURE_ALPHA_TYPE_ARB:
943 if (ctx->Extensions.ARB_texture_float) {
944 *params = img->TexFormat->AlphaBits ? img->TexFormat->DataType : GL_NONE;
945 }
946 else {
947 _mesa_error(ctx, GL_INVALID_ENUM,
948 "glGetTexLevelParameter[if]v(pname)");
949 }
950 break;
951 case GL_TEXTURE_LUMINANCE_TYPE_ARB:
952 if (ctx->Extensions.ARB_texture_float) {
953 *params = img->TexFormat->LuminanceBits ? img->TexFormat->DataType : GL_NONE;
954 }
955 else {
956 _mesa_error(ctx, GL_INVALID_ENUM,
957 "glGetTexLevelParameter[if]v(pname)");
958 }
959 break;
960 case GL_TEXTURE_INTENSITY_TYPE_ARB:
961 if (ctx->Extensions.ARB_texture_float) {
962 *params = img->TexFormat->IntensityBits ? img->TexFormat->DataType : GL_NONE;
963 }
964 else {
965 _mesa_error(ctx, GL_INVALID_ENUM,
966 "glGetTexLevelParameter[if]v(pname)");
967 }
968 break;
969 case GL_TEXTURE_DEPTH_TYPE_ARB:
970 if (ctx->Extensions.ARB_texture_float) {
971 *params = img->TexFormat->DepthBits ? img->TexFormat->DataType : GL_NONE;
972 }
973 else {
974 _mesa_error(ctx, GL_INVALID_ENUM,
975 "glGetTexLevelParameter[if]v(pname)");
976 }
977 break;
978
979 default:
980 _mesa_error(ctx, GL_INVALID_ENUM,
981 "glGetTexLevelParameter[if]v(pname)");
982 }
983
984 out:
985 _mesa_unlock_texture(ctx, texObj);
986 }
987
988
989
990 void GLAPIENTRY
991 _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
992 {
993 struct gl_texture_unit *texUnit;
994 struct gl_texture_object *obj;
995 GLboolean error = GL_FALSE;
996 GET_CURRENT_CONTEXT(ctx);
997 ASSERT_OUTSIDE_BEGIN_END(ctx);
998
999 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
1000 _mesa_error(ctx, GL_INVALID_OPERATION,
1001 "glGetTexParameterfv(current unit)");
1002 return;
1003 }
1004
1005 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1006
1007 obj = _mesa_select_tex_object(ctx, texUnit, target);
1008 if (!obj) {
1009 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
1010 return;
1011 }
1012
1013 _mesa_lock_texture(ctx, obj);
1014 switch (pname) {
1015 case GL_TEXTURE_MAG_FILTER:
1016 *params = ENUM_TO_FLOAT(obj->MagFilter);
1017 break;
1018 case GL_TEXTURE_MIN_FILTER:
1019 *params = ENUM_TO_FLOAT(obj->MinFilter);
1020 break;
1021 case GL_TEXTURE_WRAP_S:
1022 *params = ENUM_TO_FLOAT(obj->WrapS);
1023 break;
1024 case GL_TEXTURE_WRAP_T:
1025 *params = ENUM_TO_FLOAT(obj->WrapT);
1026 break;
1027 case GL_TEXTURE_WRAP_R:
1028 *params = ENUM_TO_FLOAT(obj->WrapR);
1029 break;
1030 case GL_TEXTURE_BORDER_COLOR:
1031 params[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
1032 params[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
1033 params[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
1034 params[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
1035 break;
1036 case GL_TEXTURE_RESIDENT:
1037 {
1038 GLboolean resident;
1039 if (ctx->Driver.IsTextureResident)
1040 resident = ctx->Driver.IsTextureResident(ctx, obj);
1041 else
1042 resident = GL_TRUE;
1043 *params = ENUM_TO_FLOAT(resident);
1044 }
1045 break;
1046 case GL_TEXTURE_PRIORITY:
1047 *params = obj->Priority;
1048 break;
1049 case GL_TEXTURE_MIN_LOD:
1050 *params = obj->MinLod;
1051 break;
1052 case GL_TEXTURE_MAX_LOD:
1053 *params = obj->MaxLod;
1054 break;
1055 case GL_TEXTURE_BASE_LEVEL:
1056 *params = (GLfloat) obj->BaseLevel;
1057 break;
1058 case GL_TEXTURE_MAX_LEVEL:
1059 *params = (GLfloat) obj->MaxLevel;
1060 break;
1061 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1062 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
1063 *params = obj->MaxAnisotropy;
1064 }
1065 else
1066 error = GL_TRUE;
1067 break;
1068 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
1069 if (ctx->Extensions.ARB_shadow_ambient) {
1070 *params = obj->CompareFailValue;
1071 }
1072 else
1073 error = GL_TRUE;
1074 break;
1075 case GL_GENERATE_MIPMAP_SGIS:
1076 if (ctx->Extensions.SGIS_generate_mipmap) {
1077 *params = (GLfloat) obj->GenerateMipmap;
1078 }
1079 else
1080 error = GL_TRUE;
1081 break;
1082 case GL_TEXTURE_COMPARE_MODE_ARB:
1083 if (ctx->Extensions.ARB_shadow) {
1084 *params = (GLfloat) obj->CompareMode;
1085 }
1086 else
1087 error = GL_TRUE;
1088 break;
1089 case GL_TEXTURE_COMPARE_FUNC_ARB:
1090 if (ctx->Extensions.ARB_shadow) {
1091 *params = (GLfloat) obj->CompareFunc;
1092 }
1093 else
1094 error = GL_TRUE;
1095 break;
1096 case GL_DEPTH_TEXTURE_MODE_ARB:
1097 if (ctx->Extensions.ARB_depth_texture) {
1098 *params = (GLfloat) obj->DepthMode;
1099 }
1100 else
1101 error = GL_TRUE;
1102 break;
1103 case GL_TEXTURE_LOD_BIAS:
1104 if (ctx->Extensions.EXT_texture_lod_bias) {
1105 *params = obj->LodBias;
1106 }
1107 else
1108 error = GL_TRUE;
1109 break;
1110 #ifdef FEATURE_OES_draw_texture
1111 case GL_TEXTURE_CROP_RECT_OES:
1112 params[0] = obj->CropRect[0];
1113 params[1] = obj->CropRect[1];
1114 params[2] = obj->CropRect[2];
1115 params[3] = obj->CropRect[3];
1116 break;
1117 #endif
1118
1119 case GL_TEXTURE_SWIZZLE_R_EXT:
1120 case GL_TEXTURE_SWIZZLE_G_EXT:
1121 case GL_TEXTURE_SWIZZLE_B_EXT:
1122 case GL_TEXTURE_SWIZZLE_A_EXT:
1123 if (ctx->Extensions.EXT_texture_swizzle) {
1124 GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
1125 *params = (GLfloat) obj->Swizzle[comp];
1126 }
1127 else {
1128 error = GL_TRUE;
1129 }
1130 break;
1131
1132 case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1133 if (ctx->Extensions.EXT_texture_swizzle) {
1134 GLuint comp;
1135 for (comp = 0; comp < 4; comp++) {
1136 params[comp] = (GLfloat) obj->Swizzle[comp];
1137 }
1138 }
1139 else {
1140 error = GL_TRUE;
1141 }
1142 break;
1143
1144 default:
1145 error = GL_TRUE;
1146 break;
1147 }
1148
1149 if (error)
1150 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)",
1151 pname);
1152
1153 _mesa_unlock_texture(ctx, obj);
1154 }
1155
1156
1157 void GLAPIENTRY
1158 _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
1159 {
1160 struct gl_texture_unit *texUnit;
1161 struct gl_texture_object *obj;
1162 GLboolean error = GL_FALSE;
1163 GET_CURRENT_CONTEXT(ctx);
1164 ASSERT_OUTSIDE_BEGIN_END(ctx);
1165
1166 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
1167 _mesa_error(ctx, GL_INVALID_OPERATION,
1168 "glGetTexParameteriv(current unit)");
1169 return;
1170 }
1171
1172 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1173
1174 obj = _mesa_select_tex_object(ctx, texUnit, target);
1175 if (!obj) {
1176 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)");
1177 return;
1178 }
1179
1180 switch (pname) {
1181 case GL_TEXTURE_MAG_FILTER:
1182 *params = (GLint) obj->MagFilter;
1183 break;;
1184 case GL_TEXTURE_MIN_FILTER:
1185 *params = (GLint) obj->MinFilter;
1186 break;;
1187 case GL_TEXTURE_WRAP_S:
1188 *params = (GLint) obj->WrapS;
1189 break;;
1190 case GL_TEXTURE_WRAP_T:
1191 *params = (GLint) obj->WrapT;
1192 break;;
1193 case GL_TEXTURE_WRAP_R:
1194 *params = (GLint) obj->WrapR;
1195 break;;
1196 case GL_TEXTURE_BORDER_COLOR:
1197 {
1198 GLfloat b[4];
1199 b[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
1200 b[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
1201 b[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
1202 b[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
1203 params[0] = FLOAT_TO_INT(b[0]);
1204 params[1] = FLOAT_TO_INT(b[1]);
1205 params[2] = FLOAT_TO_INT(b[2]);
1206 params[3] = FLOAT_TO_INT(b[3]);
1207 }
1208 break;;
1209 case GL_TEXTURE_RESIDENT:
1210 {
1211 GLboolean resident;
1212 if (ctx->Driver.IsTextureResident)
1213 resident = ctx->Driver.IsTextureResident(ctx, obj);
1214 else
1215 resident = GL_TRUE;
1216 *params = (GLint) resident;
1217 }
1218 break;;
1219 case GL_TEXTURE_PRIORITY:
1220 *params = FLOAT_TO_INT(obj->Priority);
1221 break;;
1222 case GL_TEXTURE_MIN_LOD:
1223 *params = (GLint) obj->MinLod;
1224 break;;
1225 case GL_TEXTURE_MAX_LOD:
1226 *params = (GLint) obj->MaxLod;
1227 break;;
1228 case GL_TEXTURE_BASE_LEVEL:
1229 *params = obj->BaseLevel;
1230 break;;
1231 case GL_TEXTURE_MAX_LEVEL:
1232 *params = obj->MaxLevel;
1233 break;;
1234 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1235 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
1236 *params = (GLint) obj->MaxAnisotropy;
1237 }
1238 else {
1239 error = GL_TRUE;
1240 }
1241 break;
1242 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
1243 if (ctx->Extensions.ARB_shadow_ambient) {
1244 *params = (GLint) FLOAT_TO_INT(obj->CompareFailValue);
1245 }
1246 else {
1247 error = GL_TRUE;
1248 }
1249 break;
1250 case GL_GENERATE_MIPMAP_SGIS:
1251 if (ctx->Extensions.SGIS_generate_mipmap) {
1252 *params = (GLint) obj->GenerateMipmap;
1253 }
1254 else {
1255 error = GL_TRUE;
1256 }
1257 break;
1258 case GL_TEXTURE_COMPARE_MODE_ARB:
1259 if (ctx->Extensions.ARB_shadow) {
1260 *params = (GLint) obj->CompareMode;
1261 }
1262 else {
1263 error = GL_TRUE;
1264 }
1265 break;
1266 case GL_TEXTURE_COMPARE_FUNC_ARB:
1267 if (ctx->Extensions.ARB_shadow) {
1268 *params = (GLint) obj->CompareFunc;
1269 }
1270 else {
1271 error = GL_TRUE;
1272 }
1273 break;
1274 case GL_DEPTH_TEXTURE_MODE_ARB:
1275 if (ctx->Extensions.ARB_depth_texture) {
1276 *params = (GLint) obj->DepthMode;
1277 }
1278 else {
1279 error = GL_TRUE;
1280 }
1281 break;
1282 case GL_TEXTURE_LOD_BIAS:
1283 if (ctx->Extensions.EXT_texture_lod_bias) {
1284 *params = (GLint) obj->LodBias;
1285 }
1286 else {
1287 error = GL_TRUE;
1288 }
1289 break;
1290 #ifdef FEATURE_OES_draw_texture
1291 case GL_TEXTURE_CROP_RECT_OES:
1292 params[0] = obj->CropRect[0];
1293 params[1] = obj->CropRect[1];
1294 params[2] = obj->CropRect[2];
1295 params[3] = obj->CropRect[3];
1296 break;
1297 #endif
1298 case GL_TEXTURE_SWIZZLE_R_EXT:
1299 case GL_TEXTURE_SWIZZLE_G_EXT:
1300 case GL_TEXTURE_SWIZZLE_B_EXT:
1301 case GL_TEXTURE_SWIZZLE_A_EXT:
1302 if (ctx->Extensions.EXT_texture_swizzle) {
1303 GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
1304 *params = obj->Swizzle[comp];
1305 }
1306 else {
1307 error = GL_TRUE;
1308 }
1309 break;
1310
1311 case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1312 if (ctx->Extensions.EXT_texture_swizzle) {
1313 COPY_4V(params, obj->Swizzle);
1314 }
1315 else {
1316 error = GL_TRUE;
1317 }
1318 break;
1319
1320 default:
1321 ; /* silence warnings */
1322 }
1323
1324 if (error)
1325 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)",
1326 pname);
1327
1328 _mesa_unlock_texture(ctx, obj);
1329 }