Merge commit 'origin/gallium-0.2' into gallium-master-merge
[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) 1999-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)" );
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->Current1D;
96 case GL_TEXTURE_2D:
97 return texUnit->Current2D;
98 case GL_TEXTURE_3D:
99 return texUnit->Current3D;
100 case GL_TEXTURE_CUBE_MAP:
101 if (ctx->Extensions.ARB_texture_cube_map) {
102 return texUnit->CurrentCubeMap;
103 }
104 break;
105 case GL_TEXTURE_RECTANGLE_NV:
106 if (ctx->Extensions.NV_texture_rectangle) {
107 return texUnit->CurrentRect;
108 }
109 break;
110 case GL_TEXTURE_1D_ARRAY_EXT:
111 if (ctx->Extensions.MESA_texture_array) {
112 return texUnit->Current1DArray;
113 }
114 break;
115 case GL_TEXTURE_2D_ARRAY_EXT:
116 if (ctx->Extensions.MESA_texture_array) {
117 return texUnit->Current2DArray;
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 /** Set an integer-valued texture parameter */
169 static void
170 set_tex_parameteri(GLcontext *ctx,
171 struct gl_texture_object *texObj,
172 GLenum pname, const GLint *params)
173 {
174 switch (pname) {
175 case GL_TEXTURE_MIN_FILTER:
176 if (texObj->MinFilter == params[0])
177 return;
178 switch (params[0]) {
179 case GL_NEAREST:
180 case GL_LINEAR:
181 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
182 texObj->MinFilter = params[0];
183 return;
184 case GL_NEAREST_MIPMAP_NEAREST:
185 case GL_LINEAR_MIPMAP_NEAREST:
186 case GL_NEAREST_MIPMAP_LINEAR:
187 case GL_LINEAR_MIPMAP_LINEAR:
188 if (texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
189 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
190 texObj->MinFilter = params[0];
191 return;
192 }
193 /* fall-through */
194 default:
195 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
196 }
197 return;
198
199 case GL_TEXTURE_MAG_FILTER:
200 if (texObj->MagFilter == params[0])
201 return;
202 switch (params[0]) {
203 case GL_NEAREST:
204 case GL_LINEAR:
205 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
206 texObj->MagFilter = params[0];
207 return;
208 default:
209 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
210 }
211 return;
212
213 case GL_TEXTURE_WRAP_S:
214 if (texObj->WrapS == params[0])
215 return;
216 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
217 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
218 texObj->WrapS = params[0];
219 }
220 return;
221
222 case GL_TEXTURE_WRAP_T:
223 if (texObj->WrapT == params[0])
224 return;
225 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
226 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
227 texObj->WrapT = params[0];
228 }
229 return;
230
231 case GL_TEXTURE_WRAP_R:
232 if (texObj->WrapR == params[0])
233 return;
234 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
235 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
236 texObj->WrapR = params[0];
237 }
238 return;
239
240 case GL_TEXTURE_BASE_LEVEL:
241 if (texObj->BaseLevel == params[0])
242 return;
243 if (params[0] < 0 ||
244 (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) {
245 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)");
246 return;
247 }
248 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
249 texObj->BaseLevel = params[0];
250 return;
251
252 case GL_TEXTURE_MAX_LEVEL:
253 if (texObj->MaxLevel == params[0])
254 return;
255 if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) {
256 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(param)");
257 return;
258 }
259 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
260 texObj->MaxLevel = params[0];
261 return;
262
263 case GL_GENERATE_MIPMAP_SGIS:
264 if (ctx->Extensions.SGIS_generate_mipmap) {
265 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
266 texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
267 }
268 else {
269 _mesa_error(ctx, GL_INVALID_ENUM,
270 "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)");
271 }
272 return;
273
274 case GL_TEXTURE_COMPARE_MODE_ARB:
275 if (ctx->Extensions.ARB_shadow &&
276 (params[0] == GL_NONE ||
277 params[0] == GL_COMPARE_R_TO_TEXTURE_ARB)) {
278 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
279 texObj->CompareMode = params[0];
280 }
281 else {
282 _mesa_error(ctx, GL_INVALID_ENUM,
283 "glTexParameter(GL_TEXTURE_COMPARE_MODE_ARB)");
284 }
285 return;
286
287 case GL_TEXTURE_COMPARE_FUNC_ARB:
288 if (ctx->Extensions.ARB_shadow) {
289 switch (params[0]) {
290 case GL_LEQUAL:
291 case GL_GEQUAL:
292 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
293 texObj->CompareFunc = params[0];
294 return;
295 case GL_EQUAL:
296 case GL_NOTEQUAL:
297 case GL_LESS:
298 case GL_GREATER:
299 case GL_ALWAYS:
300 case GL_NEVER:
301 if (ctx->Extensions.EXT_shadow_funcs) {
302 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
303 texObj->CompareFunc = params[0];
304 return;
305 }
306 /* fall-through */
307 default:
308 _mesa_error(ctx, GL_INVALID_ENUM,
309 "glTexParameter(GL_TEXTURE_COMPARE_FUNC_ARB)");
310 }
311 }
312 else {
313 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)");
314 }
315 return;
316
317 case GL_DEPTH_TEXTURE_MODE_ARB:
318 if (ctx->Extensions.ARB_depth_texture &&
319 (params[0] == GL_LUMINANCE ||
320 params[0] == GL_INTENSITY ||
321 params[0] == GL_ALPHA)) {
322 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
323 texObj->DepthMode = params[0];
324 }
325 else {
326 _mesa_error(ctx, GL_INVALID_ENUM,
327 "glTexParameter(GL_DEPTH_TEXTURE_MODE_ARB)");
328 }
329 return;
330
331 #ifdef FEATURE_OES_draw_texture
332 case GL_TEXTURE_CROP_RECT_OES:
333 texObj->CropRect[0] = params[0];
334 texObj->CropRect[1] = params[1];
335 texObj->CropRect[2] = params[2];
336 texObj->CropRect[3] = params[3];
337 return;
338 #endif
339
340 case GL_TEXTURE_SWIZZLE_R_EXT:
341 case GL_TEXTURE_SWIZZLE_G_EXT:
342 case GL_TEXTURE_SWIZZLE_B_EXT:
343 case GL_TEXTURE_SWIZZLE_A_EXT:
344 if (ctx->Extensions.EXT_texture_swizzle) {
345 const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
346 const GLint swz = comp_to_swizzle(params[0]);
347 if (swz < 0) {
348 _mesa_error(ctx, GL_INVALID_OPERATION,
349 "glTexParameter(swizzle 0x%x)", params[0]);
350 return;
351 }
352 ASSERT(comp < 4);
353 if (swz >= 0) {
354 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
355 texObj->Swizzle[comp] = params[0];
356 set_swizzle_component(&texObj->_Swizzle, comp, swz);
357 return;
358 }
359 }
360 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
361 return;
362
363 case GL_TEXTURE_SWIZZLE_RGBA_EXT:
364 if (ctx->Extensions.EXT_texture_swizzle) {
365 GLuint comp;
366 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
367 for (comp = 0; comp < 4; comp++) {
368 const GLint swz = comp_to_swizzle(params[comp]);
369 if (swz >= 0) {
370 texObj->Swizzle[comp] = params[comp];
371 set_swizzle_component(&texObj->_Swizzle, comp, swz);
372 }
373 else {
374 _mesa_error(ctx, GL_INVALID_OPERATION,
375 "glTexParameter(swizzle 0x%x)", params[comp]);
376 return;
377 }
378 }
379 return;
380 }
381 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
382 return;
383
384 default:
385 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
386 }
387 }
388
389
390 /** Set a float-valued texture parameter */
391 static void
392 set_tex_parameterf(GLcontext *ctx,
393 struct gl_texture_object *texObj,
394 GLenum pname, const GLfloat *params)
395 {
396 switch (pname) {
397 case GL_TEXTURE_MIN_LOD:
398 if (texObj->MinLod == params[0])
399 return;
400 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
401 texObj->MinLod = params[0];
402 return;
403
404 case GL_TEXTURE_MAX_LOD:
405 if (texObj->MaxLod == params[0])
406 return;
407 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
408 texObj->MaxLod = params[0];
409 return;
410
411 case GL_TEXTURE_PRIORITY:
412 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
413 texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
414 return;
415
416 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
417 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
418 if (params[0] < 1.0) {
419 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
420 return;
421 }
422 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
423 /* clamp to max, that's what NVIDIA does */
424 texObj->MaxAnisotropy = MIN2(params[0],
425 ctx->Const.MaxTextureMaxAnisotropy);
426 }
427 else {
428 _mesa_error(ctx, GL_INVALID_ENUM,
429 "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
430 }
431 return;
432
433 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
434 if (ctx->Extensions.ARB_shadow_ambient) {
435 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
436 texObj->CompareFailValue = CLAMP(params[0], 0.0F, 1.0F);
437 }
438 else {
439 _mesa_error(ctx, GL_INVALID_ENUM,
440 "glTexParameter(pname=GL_TEXTURE_COMPARE_FAIL_VALUE_ARB)");
441 }
442 return;
443
444 case GL_TEXTURE_LOD_BIAS:
445 /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias */
446 if (ctx->Extensions.EXT_texture_lod_bias) {
447 if (texObj->LodBias != params[0]) {
448 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
449 texObj->LodBias = params[0];
450 }
451 }
452 break;
453
454 case GL_TEXTURE_BORDER_COLOR:
455 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
456 texObj->BorderColor[RCOMP] = params[0];
457 texObj->BorderColor[GCOMP] = params[1];
458 texObj->BorderColor[BCOMP] = params[2];
459 texObj->BorderColor[ACOMP] = params[3];
460 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[RCOMP], params[0]);
461 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[GCOMP], params[1]);
462 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[BCOMP], params[2]);
463 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[ACOMP], params[3]);
464 return;
465
466 default:
467 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
468 }
469 }
470
471
472 void GLAPIENTRY
473 _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
474 {
475 struct gl_texture_object *texObj;
476 GET_CURRENT_CONTEXT(ctx);
477 ASSERT_OUTSIDE_BEGIN_END(ctx);
478
479 texObj = get_texobj(ctx, target);
480 if (!texObj)
481 return;
482
483 switch (pname) {
484 case GL_TEXTURE_MIN_FILTER:
485 case GL_TEXTURE_MAG_FILTER:
486 case GL_TEXTURE_WRAP_S:
487 case GL_TEXTURE_WRAP_T:
488 case GL_TEXTURE_WRAP_R:
489 case GL_TEXTURE_BASE_LEVEL:
490 case GL_TEXTURE_MAX_LEVEL:
491 case GL_GENERATE_MIPMAP_SGIS:
492 case GL_TEXTURE_COMPARE_MODE_ARB:
493 case GL_TEXTURE_COMPARE_FUNC_ARB:
494 case GL_DEPTH_TEXTURE_MODE_ARB:
495 {
496 /* convert float param to int */
497 GLint p = (GLint) param;
498 set_tex_parameteri(ctx, texObj, pname, &p);
499 }
500 return;
501 default:
502 /* this will generate an error if pname is illegal */
503 set_tex_parameterf(ctx, texObj, pname, &param);
504 }
505
506 texObj->_Complete = GL_FALSE;
507
508 if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) {
509 ctx->Driver.TexParameter(ctx, target, texObj, pname, &param);
510 }
511 }
512
513
514 void GLAPIENTRY
515 _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
516 {
517 struct gl_texture_object *texObj;
518 GET_CURRENT_CONTEXT(ctx);
519 ASSERT_OUTSIDE_BEGIN_END(ctx);
520
521 texObj = get_texobj(ctx, target);
522 if (!texObj)
523 return;
524
525 switch (pname) {
526 case GL_TEXTURE_MIN_FILTER:
527 case GL_TEXTURE_MAG_FILTER:
528 case GL_TEXTURE_WRAP_S:
529 case GL_TEXTURE_WRAP_T:
530 case GL_TEXTURE_WRAP_R:
531 case GL_TEXTURE_BASE_LEVEL:
532 case GL_TEXTURE_MAX_LEVEL:
533 case GL_GENERATE_MIPMAP_SGIS:
534 case GL_TEXTURE_COMPARE_MODE_ARB:
535 case GL_TEXTURE_COMPARE_FUNC_ARB:
536 case GL_DEPTH_TEXTURE_MODE_ARB:
537 {
538 /* convert float param to int */
539 GLint p = (GLint) params[0];
540 set_tex_parameteri(ctx, texObj, pname, &p);
541 }
542 break;
543
544 #ifdef FEATURE_OES_draw_texture
545 case GL_TEXTURE_CROP_RECT_OES:
546 {
547 /* convert float params to int */
548 GLint iparams[4];
549 iparams[0] = (GLint) params[0];
550 iparams[1] = (GLint) params[1];
551 iparams[2] = (GLint) params[2];
552 iparams[3] = (GLint) params[3];
553 set_tex_parameteri(ctx, target, iparams);
554 }
555 break;
556 #endif
557
558 default:
559 /* this will generate an error if pname is illegal */
560 set_tex_parameterf(ctx, texObj, pname, params);
561 }
562
563 texObj->_Complete = GL_FALSE;
564
565 if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) {
566 ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
567 }
568 }
569
570
571 void GLAPIENTRY
572 _mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
573 {
574 struct gl_texture_object *texObj;
575 GET_CURRENT_CONTEXT(ctx);
576 ASSERT_OUTSIDE_BEGIN_END(ctx);
577
578 texObj = get_texobj(ctx, target);
579 if (!texObj)
580 return;
581
582 switch (pname) {
583 case GL_TEXTURE_MIN_LOD:
584 case GL_TEXTURE_MAX_LOD:
585 case GL_TEXTURE_PRIORITY:
586 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
587 case GL_TEXTURE_LOD_BIAS:
588 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
589 {
590 GLfloat fparam = (GLfloat) param;
591 /* convert int param to float */
592 set_tex_parameterf(ctx, texObj, pname, &fparam);
593 }
594 break;
595 default:
596 /* this will generate an error if pname is illegal */
597 set_tex_parameteri(ctx, texObj, pname, &param);
598 }
599
600 texObj->_Complete = GL_FALSE;
601
602 if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) {
603 GLfloat fparam = (GLfloat) param;
604 ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam);
605 }
606 }
607
608
609 void GLAPIENTRY
610 _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
611 {
612 struct gl_texture_object *texObj;
613 GET_CURRENT_CONTEXT(ctx);
614 ASSERT_OUTSIDE_BEGIN_END(ctx);
615
616 texObj = get_texobj(ctx, target);
617 if (!texObj)
618 return;
619
620 switch (pname) {
621 case GL_TEXTURE_BORDER_COLOR:
622 {
623 /* convert int params to float */
624 GLfloat fparams[4];
625 fparams[0] = INT_TO_FLOAT(params[0]);
626 fparams[1] = INT_TO_FLOAT(params[1]);
627 fparams[2] = INT_TO_FLOAT(params[2]);
628 fparams[3] = INT_TO_FLOAT(params[3]);
629 set_tex_parameterf(ctx, texObj, pname, fparams);
630 }
631 break;
632 case GL_TEXTURE_MIN_LOD:
633 case GL_TEXTURE_MAX_LOD:
634 case GL_TEXTURE_PRIORITY:
635 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
636 case GL_TEXTURE_LOD_BIAS:
637 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
638 {
639 /* convert int param to float */
640 GLfloat fparam = (GLfloat) params[0];
641 set_tex_parameterf(ctx, texObj, pname, &fparam);
642 }
643 break;
644 default:
645 /* this will generate an error if pname is illegal */
646 set_tex_parameteri(ctx, texObj, pname, params);
647 }
648
649 texObj->_Complete = GL_FALSE;
650
651 if (ctx->Driver.TexParameter && ctx->ErrorValue == GL_NO_ERROR) {
652 GLfloat fparams[4];
653 fparams[0] = INT_TO_FLOAT(params[0]);
654 if (pname == GL_TEXTURE_BORDER_COLOR ||
655 pname == GL_TEXTURE_CROP_RECT_OES) {
656 fparams[1] = INT_TO_FLOAT(params[1]);
657 fparams[2] = INT_TO_FLOAT(params[2]);
658 fparams[3] = INT_TO_FLOAT(params[3]);
659 }
660 ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams);
661 }
662 }
663
664
665 void GLAPIENTRY
666 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
667 GLenum pname, GLfloat *params )
668 {
669 GLint iparam;
670 _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
671 *params = (GLfloat) iparam;
672 }
673
674
675 static GLuint
676 tex_image_dimensions(GLcontext *ctx, GLenum target)
677 {
678 switch (target) {
679 case GL_TEXTURE_1D:
680 case GL_PROXY_TEXTURE_1D:
681 return 1;
682 case GL_TEXTURE_2D:
683 case GL_PROXY_TEXTURE_2D:
684 return 2;
685 case GL_TEXTURE_3D:
686 case GL_PROXY_TEXTURE_3D:
687 return 3;
688 case GL_TEXTURE_CUBE_MAP:
689 case GL_PROXY_TEXTURE_CUBE_MAP:
690 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
691 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
692 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
693 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
694 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
695 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
696 return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
697 case GL_TEXTURE_RECTANGLE_NV:
698 case GL_PROXY_TEXTURE_RECTANGLE_NV:
699 return ctx->Extensions.NV_texture_rectangle ? 2 : 0;
700 case GL_TEXTURE_1D_ARRAY_EXT:
701 case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
702 return ctx->Extensions.MESA_texture_array ? 2 : 0;
703 case GL_TEXTURE_2D_ARRAY_EXT:
704 case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
705 return ctx->Extensions.MESA_texture_array ? 3 : 0;
706 default:
707 _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
708 return 0;
709 }
710 }
711
712
713 void GLAPIENTRY
714 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
715 GLenum pname, GLint *params )
716 {
717 const struct gl_texture_unit *texUnit;
718 struct gl_texture_object *texObj;
719 const struct gl_texture_image *img = NULL;
720 GLuint dimensions;
721 GLboolean isProxy;
722 GLint maxLevels;
723 GET_CURRENT_CONTEXT(ctx);
724 ASSERT_OUTSIDE_BEGIN_END(ctx);
725
726 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
727 _mesa_error(ctx, GL_INVALID_OPERATION,
728 "glGetTexLevelParameteriv(current unit)");
729 return;
730 }
731
732 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
733
734 /* this will catch bad target values */
735 dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */
736 if (dimensions == 0) {
737 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
738 return;
739 }
740
741 maxLevels = _mesa_max_texture_levels(ctx, target);
742 if (maxLevels == 0) {
743 /* should not happen since <target> was just checked above */
744 _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter");
745 return;
746 }
747
748 if (level < 0 || level >= maxLevels) {
749 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
750 return;
751 }
752
753 texObj = _mesa_select_tex_object(ctx, texUnit, target);
754 _mesa_lock_texture(ctx, texObj);
755
756 img = _mesa_select_tex_image(ctx, texObj, target, level);
757 if (!img || !img->TexFormat) {
758 /* undefined texture image */
759 if (pname == GL_TEXTURE_COMPONENTS)
760 *params = 1;
761 else
762 *params = 0;
763 goto out;
764 }
765
766 isProxy = _mesa_is_proxy_texture(target);
767
768 switch (pname) {
769 case GL_TEXTURE_WIDTH:
770 *params = img->Width;
771 break;
772 case GL_TEXTURE_HEIGHT:
773 *params = img->Height;
774 break;
775 case GL_TEXTURE_DEPTH:
776 *params = img->Depth;
777 break;
778 case GL_TEXTURE_INTERNAL_FORMAT:
779 *params = img->InternalFormat;
780 break;
781 case GL_TEXTURE_BORDER:
782 *params = img->Border;
783 break;
784 case GL_TEXTURE_RED_SIZE:
785 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
786 *params = img->TexFormat->RedBits;
787 else
788 *params = 0;
789 break;
790 case GL_TEXTURE_GREEN_SIZE:
791 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
792 *params = img->TexFormat->GreenBits;
793 else
794 *params = 0;
795 break;
796 case GL_TEXTURE_BLUE_SIZE:
797 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
798 *params = img->TexFormat->BlueBits;
799 else
800 *params = 0;
801 break;
802 case GL_TEXTURE_ALPHA_SIZE:
803 if (img->_BaseFormat == GL_ALPHA ||
804 img->_BaseFormat == GL_LUMINANCE_ALPHA ||
805 img->_BaseFormat == GL_RGBA)
806 *params = img->TexFormat->AlphaBits;
807 else
808 *params = 0;
809 break;
810 case GL_TEXTURE_INTENSITY_SIZE:
811 if (img->_BaseFormat != GL_INTENSITY)
812 *params = 0;
813 else if (img->TexFormat->IntensityBits > 0)
814 *params = img->TexFormat->IntensityBits;
815 else /* intensity probably stored as rgb texture */
816 *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
817 break;
818 case GL_TEXTURE_LUMINANCE_SIZE:
819 if (img->_BaseFormat != GL_LUMINANCE &&
820 img->_BaseFormat != GL_LUMINANCE_ALPHA)
821 *params = 0;
822 else if (img->TexFormat->LuminanceBits > 0)
823 *params = img->TexFormat->LuminanceBits;
824 else /* luminance probably stored as rgb texture */
825 *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
826 break;
827 case GL_TEXTURE_INDEX_SIZE_EXT:
828 if (img->_BaseFormat == GL_COLOR_INDEX)
829 *params = img->TexFormat->IndexBits;
830 else
831 *params = 0;
832 break;
833 case GL_TEXTURE_DEPTH_SIZE_ARB:
834 if (ctx->Extensions.ARB_depth_texture)
835 *params = img->TexFormat->DepthBits;
836 else
837 _mesa_error(ctx, GL_INVALID_ENUM,
838 "glGetTexLevelParameter[if]v(pname)");
839 break;
840 case GL_TEXTURE_STENCIL_SIZE_EXT:
841 if (ctx->Extensions.EXT_packed_depth_stencil) {
842 *params = img->TexFormat->StencilBits;
843 }
844 else {
845 _mesa_error(ctx, GL_INVALID_ENUM,
846 "glGetTexLevelParameter[if]v(pname)");
847 }
848 break;
849
850 /* GL_ARB_texture_compression */
851 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
852 if (img->IsCompressed && !isProxy) {
853 /* Don't use ctx->Driver.CompressedTextureSize() since that
854 * may returned a padded hardware size.
855 */
856 *params = _mesa_compressed_texture_size(ctx, img->Width,
857 img->Height, img->Depth,
858 img->TexFormat->MesaFormat);
859 }
860 else {
861 _mesa_error(ctx, GL_INVALID_OPERATION,
862 "glGetTexLevelParameter[if]v(pname)");
863 }
864 break;
865 case GL_TEXTURE_COMPRESSED:
866 *params = (GLint) img->IsCompressed;
867 break;
868
869 /* GL_ARB_texture_float */
870 case GL_TEXTURE_RED_TYPE_ARB:
871 if (ctx->Extensions.ARB_texture_float) {
872 *params = img->TexFormat->RedBits ? img->TexFormat->DataType : GL_NONE;
873 }
874 else {
875 _mesa_error(ctx, GL_INVALID_ENUM,
876 "glGetTexLevelParameter[if]v(pname)");
877 }
878 break;
879 case GL_TEXTURE_GREEN_TYPE_ARB:
880 if (ctx->Extensions.ARB_texture_float) {
881 *params = img->TexFormat->GreenBits ? img->TexFormat->DataType : GL_NONE;
882 }
883 else {
884 _mesa_error(ctx, GL_INVALID_ENUM,
885 "glGetTexLevelParameter[if]v(pname)");
886 }
887 break;
888 case GL_TEXTURE_BLUE_TYPE_ARB:
889 if (ctx->Extensions.ARB_texture_float) {
890 *params = img->TexFormat->BlueBits ? img->TexFormat->DataType : GL_NONE;
891 }
892 else {
893 _mesa_error(ctx, GL_INVALID_ENUM,
894 "glGetTexLevelParameter[if]v(pname)");
895 }
896 break;
897 case GL_TEXTURE_ALPHA_TYPE_ARB:
898 if (ctx->Extensions.ARB_texture_float) {
899 *params = img->TexFormat->AlphaBits ? img->TexFormat->DataType : GL_NONE;
900 }
901 else {
902 _mesa_error(ctx, GL_INVALID_ENUM,
903 "glGetTexLevelParameter[if]v(pname)");
904 }
905 break;
906 case GL_TEXTURE_LUMINANCE_TYPE_ARB:
907 if (ctx->Extensions.ARB_texture_float) {
908 *params = img->TexFormat->LuminanceBits ? img->TexFormat->DataType : GL_NONE;
909 }
910 else {
911 _mesa_error(ctx, GL_INVALID_ENUM,
912 "glGetTexLevelParameter[if]v(pname)");
913 }
914 break;
915 case GL_TEXTURE_INTENSITY_TYPE_ARB:
916 if (ctx->Extensions.ARB_texture_float) {
917 *params = img->TexFormat->IntensityBits ? 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_DEPTH_TYPE_ARB:
925 if (ctx->Extensions.ARB_texture_float) {
926 *params = img->TexFormat->DepthBits ? img->TexFormat->DataType : GL_NONE;
927 }
928 else {
929 _mesa_error(ctx, GL_INVALID_ENUM,
930 "glGetTexLevelParameter[if]v(pname)");
931 }
932 break;
933
934 default:
935 _mesa_error(ctx, GL_INVALID_ENUM,
936 "glGetTexLevelParameter[if]v(pname)");
937 }
938
939 out:
940 _mesa_unlock_texture(ctx, texObj);
941 }
942
943
944
945 void GLAPIENTRY
946 _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
947 {
948 struct gl_texture_unit *texUnit;
949 struct gl_texture_object *obj;
950 GLboolean error = GL_FALSE;
951 GET_CURRENT_CONTEXT(ctx);
952 ASSERT_OUTSIDE_BEGIN_END(ctx);
953
954 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
955 _mesa_error(ctx, GL_INVALID_OPERATION,
956 "glGetTexParameterfv(current unit)");
957 return;
958 }
959
960 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
961
962 obj = _mesa_select_tex_object(ctx, texUnit, target);
963 if (!obj) {
964 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
965 return;
966 }
967
968 _mesa_lock_texture(ctx, obj);
969 switch (pname) {
970 case GL_TEXTURE_MAG_FILTER:
971 *params = ENUM_TO_FLOAT(obj->MagFilter);
972 break;
973 case GL_TEXTURE_MIN_FILTER:
974 *params = ENUM_TO_FLOAT(obj->MinFilter);
975 break;
976 case GL_TEXTURE_WRAP_S:
977 *params = ENUM_TO_FLOAT(obj->WrapS);
978 break;
979 case GL_TEXTURE_WRAP_T:
980 *params = ENUM_TO_FLOAT(obj->WrapT);
981 break;
982 case GL_TEXTURE_WRAP_R:
983 *params = ENUM_TO_FLOAT(obj->WrapR);
984 break;
985 case GL_TEXTURE_BORDER_COLOR:
986 params[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
987 params[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
988 params[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
989 params[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
990 break;
991 case GL_TEXTURE_RESIDENT:
992 {
993 GLboolean resident;
994 if (ctx->Driver.IsTextureResident)
995 resident = ctx->Driver.IsTextureResident(ctx, obj);
996 else
997 resident = GL_TRUE;
998 *params = ENUM_TO_FLOAT(resident);
999 }
1000 break;
1001 case GL_TEXTURE_PRIORITY:
1002 *params = obj->Priority;
1003 break;
1004 case GL_TEXTURE_MIN_LOD:
1005 *params = obj->MinLod;
1006 break;
1007 case GL_TEXTURE_MAX_LOD:
1008 *params = obj->MaxLod;
1009 break;
1010 case GL_TEXTURE_BASE_LEVEL:
1011 *params = (GLfloat) obj->BaseLevel;
1012 break;
1013 case GL_TEXTURE_MAX_LEVEL:
1014 *params = (GLfloat) obj->MaxLevel;
1015 break;
1016 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1017 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
1018 *params = obj->MaxAnisotropy;
1019 }
1020 else
1021 error = GL_TRUE;
1022 break;
1023 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
1024 if (ctx->Extensions.ARB_shadow_ambient) {
1025 *params = obj->CompareFailValue;
1026 }
1027 else
1028 error = GL_TRUE;
1029 break;
1030 case GL_GENERATE_MIPMAP_SGIS:
1031 if (ctx->Extensions.SGIS_generate_mipmap) {
1032 *params = (GLfloat) obj->GenerateMipmap;
1033 }
1034 else
1035 error = GL_TRUE;
1036 break;
1037 case GL_TEXTURE_COMPARE_MODE_ARB:
1038 if (ctx->Extensions.ARB_shadow) {
1039 *params = (GLfloat) obj->CompareMode;
1040 }
1041 else
1042 error = GL_TRUE;
1043 break;
1044 case GL_TEXTURE_COMPARE_FUNC_ARB:
1045 if (ctx->Extensions.ARB_shadow) {
1046 *params = (GLfloat) obj->CompareFunc;
1047 }
1048 else
1049 error = GL_TRUE;
1050 break;
1051 case GL_DEPTH_TEXTURE_MODE_ARB:
1052 if (ctx->Extensions.ARB_depth_texture) {
1053 *params = (GLfloat) obj->DepthMode;
1054 }
1055 else
1056 error = GL_TRUE;
1057 break;
1058 case GL_TEXTURE_LOD_BIAS:
1059 if (ctx->Extensions.EXT_texture_lod_bias) {
1060 *params = obj->LodBias;
1061 }
1062 else
1063 error = GL_TRUE;
1064 break;
1065 #ifdef FEATURE_OES_draw_texture
1066 case GL_TEXTURE_CROP_RECT_OES:
1067 params[0] = obj->CropRect[0];
1068 params[1] = obj->CropRect[1];
1069 params[2] = obj->CropRect[2];
1070 params[3] = obj->CropRect[3];
1071 break;
1072 #endif
1073
1074 case GL_TEXTURE_SWIZZLE_R_EXT:
1075 case GL_TEXTURE_SWIZZLE_G_EXT:
1076 case GL_TEXTURE_SWIZZLE_B_EXT:
1077 case GL_TEXTURE_SWIZZLE_A_EXT:
1078 if (ctx->Extensions.EXT_texture_swizzle) {
1079 GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
1080 *params = (GLfloat) obj->Swizzle[comp];
1081 }
1082 else {
1083 error = GL_TRUE;
1084 }
1085 break;
1086
1087 case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1088 if (ctx->Extensions.EXT_texture_swizzle) {
1089 GLuint comp;
1090 for (comp = 0; comp < 4; comp++) {
1091 params[comp] = (GLfloat) obj->Swizzle[comp];
1092 }
1093 }
1094 else {
1095 error = GL_TRUE;
1096 }
1097 break;
1098
1099 default:
1100 error = GL_TRUE;
1101 break;
1102 }
1103
1104 if (error)
1105 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)",
1106 pname);
1107
1108 _mesa_unlock_texture(ctx, obj);
1109 }
1110
1111
1112 void GLAPIENTRY
1113 _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
1114 {
1115 struct gl_texture_unit *texUnit;
1116 struct gl_texture_object *obj;
1117 GLboolean error = GL_FALSE;
1118 GET_CURRENT_CONTEXT(ctx);
1119 ASSERT_OUTSIDE_BEGIN_END(ctx);
1120
1121 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
1122 _mesa_error(ctx, GL_INVALID_OPERATION,
1123 "glGetTexParameteriv(current unit)");
1124 return;
1125 }
1126
1127 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
1128
1129 obj = _mesa_select_tex_object(ctx, texUnit, target);
1130 if (!obj) {
1131 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)");
1132 return;
1133 }
1134
1135 switch (pname) {
1136 case GL_TEXTURE_MAG_FILTER:
1137 *params = (GLint) obj->MagFilter;
1138 break;;
1139 case GL_TEXTURE_MIN_FILTER:
1140 *params = (GLint) obj->MinFilter;
1141 break;;
1142 case GL_TEXTURE_WRAP_S:
1143 *params = (GLint) obj->WrapS;
1144 break;;
1145 case GL_TEXTURE_WRAP_T:
1146 *params = (GLint) obj->WrapT;
1147 break;;
1148 case GL_TEXTURE_WRAP_R:
1149 *params = (GLint) obj->WrapR;
1150 break;;
1151 case GL_TEXTURE_BORDER_COLOR:
1152 {
1153 GLfloat b[4];
1154 b[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
1155 b[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
1156 b[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
1157 b[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
1158 params[0] = FLOAT_TO_INT(b[0]);
1159 params[1] = FLOAT_TO_INT(b[1]);
1160 params[2] = FLOAT_TO_INT(b[2]);
1161 params[3] = FLOAT_TO_INT(b[3]);
1162 }
1163 break;;
1164 case GL_TEXTURE_RESIDENT:
1165 {
1166 GLboolean resident;
1167 if (ctx->Driver.IsTextureResident)
1168 resident = ctx->Driver.IsTextureResident(ctx, obj);
1169 else
1170 resident = GL_TRUE;
1171 *params = (GLint) resident;
1172 }
1173 break;;
1174 case GL_TEXTURE_PRIORITY:
1175 *params = FLOAT_TO_INT(obj->Priority);
1176 break;;
1177 case GL_TEXTURE_MIN_LOD:
1178 *params = (GLint) obj->MinLod;
1179 break;;
1180 case GL_TEXTURE_MAX_LOD:
1181 *params = (GLint) obj->MaxLod;
1182 break;;
1183 case GL_TEXTURE_BASE_LEVEL:
1184 *params = obj->BaseLevel;
1185 break;;
1186 case GL_TEXTURE_MAX_LEVEL:
1187 *params = obj->MaxLevel;
1188 break;;
1189 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1190 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
1191 *params = (GLint) obj->MaxAnisotropy;
1192 }
1193 else {
1194 error = GL_TRUE;
1195 }
1196 break;
1197 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
1198 if (ctx->Extensions.ARB_shadow_ambient) {
1199 *params = (GLint) FLOAT_TO_INT(obj->CompareFailValue);
1200 }
1201 else {
1202 error = GL_TRUE;
1203 }
1204 break;
1205 case GL_GENERATE_MIPMAP_SGIS:
1206 if (ctx->Extensions.SGIS_generate_mipmap) {
1207 *params = (GLint) obj->GenerateMipmap;
1208 }
1209 else {
1210 error = GL_TRUE;
1211 }
1212 break;
1213 case GL_TEXTURE_COMPARE_MODE_ARB:
1214 if (ctx->Extensions.ARB_shadow) {
1215 *params = (GLint) obj->CompareMode;
1216 }
1217 else {
1218 error = GL_TRUE;
1219 }
1220 break;
1221 case GL_TEXTURE_COMPARE_FUNC_ARB:
1222 if (ctx->Extensions.ARB_shadow) {
1223 *params = (GLint) obj->CompareFunc;
1224 }
1225 else {
1226 error = GL_TRUE;
1227 }
1228 break;
1229 case GL_DEPTH_TEXTURE_MODE_ARB:
1230 if (ctx->Extensions.ARB_depth_texture) {
1231 *params = (GLint) obj->DepthMode;
1232 }
1233 else {
1234 error = GL_TRUE;
1235 }
1236 break;
1237 case GL_TEXTURE_LOD_BIAS:
1238 if (ctx->Extensions.EXT_texture_lod_bias) {
1239 *params = (GLint) obj->LodBias;
1240 }
1241 else {
1242 error = GL_TRUE;
1243 }
1244 break;
1245 #ifdef FEATURE_OES_draw_texture
1246 case GL_TEXTURE_CROP_RECT_OES:
1247 params[0] = obj->CropRect[0];
1248 params[1] = obj->CropRect[1];
1249 params[2] = obj->CropRect[2];
1250 params[3] = obj->CropRect[3];
1251 break;
1252 #endif
1253 case GL_TEXTURE_SWIZZLE_R_EXT:
1254 case GL_TEXTURE_SWIZZLE_G_EXT:
1255 case GL_TEXTURE_SWIZZLE_B_EXT:
1256 case GL_TEXTURE_SWIZZLE_A_EXT:
1257 if (ctx->Extensions.EXT_texture_swizzle) {
1258 GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
1259 *params = obj->Swizzle[comp];
1260 }
1261 else {
1262 error = GL_TRUE;
1263 }
1264 break;
1265
1266 case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1267 if (ctx->Extensions.EXT_texture_swizzle) {
1268 COPY_4V(params, obj->Swizzle);
1269 }
1270 else {
1271 error = GL_TRUE;
1272 }
1273 break;
1274
1275 default:
1276 ; /* silence warnings */
1277 }
1278
1279 if (error)
1280 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)",
1281 pname);
1282
1283 _mesa_unlock_texture(ctx, obj);
1284 }