mesa: use _mesa_get_format_bits()
[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/colormac.h"
35 #include "main/context.h"
36 #include "main/enums.h"
37 #include "main/formats.h"
38 #include "main/macros.h"
39 #include "main/texcompress.h"
40 #include "main/texparam.h"
41 #include "main/teximage.h"
42 #include "main/texstate.h"
43 #include "shader/prog_instruction.h"
44
45
46 /**
47 * Check if a coordinate wrap mode is supported for the texture target.
48 * \return GL_TRUE if legal, GL_FALSE otherwise
49 */
50 static GLboolean
51 validate_texture_wrap_mode(GLcontext * ctx, GLenum target, GLenum wrap)
52 {
53 const struct gl_extensions * const e = & ctx->Extensions;
54
55 if (wrap == GL_CLAMP || wrap == GL_CLAMP_TO_EDGE ||
56 (wrap == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
57 /* any texture target */
58 return GL_TRUE;
59 }
60 else if (target != GL_TEXTURE_RECTANGLE_NV &&
61 (wrap == GL_REPEAT ||
62 (wrap == GL_MIRRORED_REPEAT &&
63 e->ARB_texture_mirrored_repeat) ||
64 (wrap == GL_MIRROR_CLAMP_EXT &&
65 (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
66 (wrap == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
67 (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
68 (wrap == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
69 (e->EXT_texture_mirror_clamp)))) {
70 /* non-rectangle texture */
71 return GL_TRUE;
72 }
73
74 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap );
75 return GL_FALSE;
76 }
77
78
79 /**
80 * Get current texture object for given target.
81 * Return NULL if any error.
82 */
83 static struct gl_texture_object *
84 get_texobj(GLcontext *ctx, GLenum target)
85 {
86 struct gl_texture_unit *texUnit;
87
88 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
89 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(current unit)");
90 return NULL;
91 }
92
93 texUnit = _mesa_get_current_tex_unit(ctx);
94
95 switch (target) {
96 case GL_TEXTURE_1D:
97 return texUnit->CurrentTex[TEXTURE_1D_INDEX];
98 case GL_TEXTURE_2D:
99 return texUnit->CurrentTex[TEXTURE_2D_INDEX];
100 case GL_TEXTURE_3D:
101 return texUnit->CurrentTex[TEXTURE_3D_INDEX];
102 case GL_TEXTURE_CUBE_MAP:
103 if (ctx->Extensions.ARB_texture_cube_map) {
104 return texUnit->CurrentTex[TEXTURE_CUBE_INDEX];
105 }
106 break;
107 case GL_TEXTURE_RECTANGLE_NV:
108 if (ctx->Extensions.NV_texture_rectangle) {
109 return texUnit->CurrentTex[TEXTURE_RECT_INDEX];
110 }
111 break;
112 case GL_TEXTURE_1D_ARRAY_EXT:
113 if (ctx->Extensions.MESA_texture_array) {
114 return texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX];
115 }
116 break;
117 case GL_TEXTURE_2D_ARRAY_EXT:
118 if (ctx->Extensions.MESA_texture_array) {
119 return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX];
120 }
121 break;
122 default:
123 ;
124 }
125
126 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(target)");
127 return NULL;
128 }
129
130
131 /**
132 * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE.
133 * \return -1 if error.
134 */
135 static GLint
136 comp_to_swizzle(GLenum comp)
137 {
138 switch (comp) {
139 case GL_RED:
140 return SWIZZLE_X;
141 case GL_GREEN:
142 return SWIZZLE_Y;
143 case GL_BLUE:
144 return SWIZZLE_Z;
145 case GL_ALPHA:
146 return SWIZZLE_W;
147 case GL_ZERO:
148 return SWIZZLE_ZERO;
149 case GL_ONE:
150 return SWIZZLE_ONE;
151 default:
152 return -1;
153 }
154 }
155
156
157 static void
158 set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz)
159 {
160 ASSERT(comp < 4);
161 ASSERT(swz <= SWIZZLE_NIL);
162 {
163 GLuint mask = 0x7 << (3 * comp);
164 GLuint s = (*swizzle & ~mask) | (swz << (3 * comp));
165 *swizzle = s;
166 }
167 }
168
169
170 /**
171 * This is called just prior to changing any texture object state.
172 * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE
173 * state flag and then mark the texture object as 'incomplete' so that any
174 * per-texture derived state gets recomputed.
175 */
176 static INLINE void
177 flush(GLcontext *ctx, struct gl_texture_object *texObj)
178 {
179 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
180 texObj->_Complete = GL_FALSE;
181 }
182
183
184 /**
185 * Set an integer-valued texture parameter
186 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
187 */
188 static GLboolean
189 set_tex_parameteri(GLcontext *ctx,
190 struct gl_texture_object *texObj,
191 GLenum pname, const GLint *params)
192 {
193 switch (pname) {
194 case GL_TEXTURE_MIN_FILTER:
195 if (texObj->MinFilter == params[0])
196 return GL_FALSE;
197 switch (params[0]) {
198 case GL_NEAREST:
199 case GL_LINEAR:
200 flush(ctx, texObj);
201 texObj->MinFilter = params[0];
202 return GL_TRUE;
203 case GL_NEAREST_MIPMAP_NEAREST:
204 case GL_LINEAR_MIPMAP_NEAREST:
205 case GL_NEAREST_MIPMAP_LINEAR:
206 case GL_LINEAR_MIPMAP_LINEAR:
207 if (texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
208 flush(ctx, texObj);
209 texObj->MinFilter = params[0];
210 return GL_TRUE;
211 }
212 /* fall-through */
213 default:
214 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)",
215 params[0] );
216 }
217 return GL_FALSE;
218
219 case GL_TEXTURE_MAG_FILTER:
220 if (texObj->MagFilter == params[0])
221 return GL_FALSE;
222 switch (params[0]) {
223 case GL_NEAREST:
224 case GL_LINEAR:
225 flush(ctx, texObj);
226 texObj->MagFilter = params[0];
227 return GL_TRUE;
228 default:
229 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)",
230 params[0]);
231 }
232 return GL_FALSE;
233
234 case GL_TEXTURE_WRAP_S:
235 if (texObj->WrapS == params[0])
236 return GL_FALSE;
237 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
238 flush(ctx, texObj);
239 texObj->WrapS = params[0];
240 return GL_TRUE;
241 }
242 return GL_FALSE;
243
244 case GL_TEXTURE_WRAP_T:
245 if (texObj->WrapT == params[0])
246 return GL_FALSE;
247 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
248 flush(ctx, texObj);
249 texObj->WrapT = params[0];
250 return GL_TRUE;
251 }
252 return GL_FALSE;
253
254 case GL_TEXTURE_WRAP_R:
255 if (texObj->WrapR == params[0])
256 return GL_FALSE;
257 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
258 flush(ctx, texObj);
259 texObj->WrapR = params[0];
260 return GL_TRUE;
261 }
262 return GL_FALSE;
263
264 case GL_TEXTURE_BASE_LEVEL:
265 if (texObj->BaseLevel == params[0])
266 return GL_FALSE;
267 if (params[0] < 0 ||
268 (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) {
269 _mesa_error(ctx, GL_INVALID_VALUE,
270 "glTexParameter(param=%d)", params[0]);
271 return GL_FALSE;
272 }
273 flush(ctx, texObj);
274 texObj->BaseLevel = params[0];
275 return GL_TRUE;
276
277 case GL_TEXTURE_MAX_LEVEL:
278 if (texObj->MaxLevel == params[0])
279 return GL_FALSE;
280 if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) {
281 _mesa_error(ctx, GL_INVALID_OPERATION,
282 "glTexParameter(param=%d)", params[0]);
283 return GL_FALSE;
284 }
285 flush(ctx, texObj);
286 texObj->MaxLevel = params[0];
287 return GL_TRUE;
288
289 case GL_GENERATE_MIPMAP_SGIS:
290 if (ctx->Extensions.SGIS_generate_mipmap) {
291 if (texObj->GenerateMipmap != params[0]) {
292 flush(ctx, texObj);
293 texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
294 return GL_TRUE;
295 }
296 return GL_FALSE;
297 }
298 else {
299 _mesa_error(ctx, GL_INVALID_ENUM,
300 "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)");
301 }
302 return GL_FALSE;
303
304 case GL_TEXTURE_COMPARE_MODE_ARB:
305 if (ctx->Extensions.ARB_shadow &&
306 (params[0] == GL_NONE ||
307 params[0] == GL_COMPARE_R_TO_TEXTURE_ARB)) {
308 if (texObj->CompareMode != params[0]) {
309 flush(ctx, texObj);
310 texObj->CompareMode = params[0];
311 return GL_TRUE;
312 }
313 return GL_FALSE;
314 }
315 else {
316 _mesa_error(ctx, GL_INVALID_ENUM,
317 "glTexParameter(GL_TEXTURE_COMPARE_MODE_ARB)");
318 }
319 return GL_FALSE;
320
321 case GL_TEXTURE_COMPARE_FUNC_ARB:
322 if (ctx->Extensions.ARB_shadow) {
323 if (texObj->CompareFunc == params[0])
324 return GL_FALSE;
325 switch (params[0]) {
326 case GL_LEQUAL:
327 case GL_GEQUAL:
328 flush(ctx, texObj);
329 texObj->CompareFunc = params[0];
330 return GL_TRUE;
331 case GL_EQUAL:
332 case GL_NOTEQUAL:
333 case GL_LESS:
334 case GL_GREATER:
335 case GL_ALWAYS:
336 case GL_NEVER:
337 if (ctx->Extensions.EXT_shadow_funcs) {
338 flush(ctx, texObj);
339 texObj->CompareFunc = params[0];
340 return GL_TRUE;
341 }
342 /* fall-through */
343 default:
344 _mesa_error(ctx, GL_INVALID_ENUM,
345 "glTexParameter(GL_TEXTURE_COMPARE_FUNC_ARB)");
346 }
347 }
348 else {
349 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
350 }
351 return GL_FALSE;
352
353 case GL_DEPTH_TEXTURE_MODE_ARB:
354 if (ctx->Extensions.ARB_depth_texture &&
355 (params[0] == GL_LUMINANCE ||
356 params[0] == GL_INTENSITY ||
357 params[0] == GL_ALPHA)) {
358 if (texObj->DepthMode != params[0]) {
359 flush(ctx, texObj);
360 texObj->DepthMode = params[0];
361 return GL_TRUE;
362 }
363 }
364 else {
365 _mesa_error(ctx, GL_INVALID_ENUM,
366 "glTexParameter(GL_DEPTH_TEXTURE_MODE_ARB)");
367 }
368 return GL_FALSE;
369
370 #ifdef FEATURE_OES_draw_texture
371 case GL_TEXTURE_CROP_RECT_OES:
372 texObj->CropRect[0] = params[0];
373 texObj->CropRect[1] = params[1];
374 texObj->CropRect[2] = params[2];
375 texObj->CropRect[3] = params[3];
376 return GL_TRUE;
377 #endif
378
379 case GL_TEXTURE_SWIZZLE_R_EXT:
380 case GL_TEXTURE_SWIZZLE_G_EXT:
381 case GL_TEXTURE_SWIZZLE_B_EXT:
382 case GL_TEXTURE_SWIZZLE_A_EXT:
383 if (ctx->Extensions.EXT_texture_swizzle) {
384 const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
385 const GLint swz = comp_to_swizzle(params[0]);
386 if (swz < 0) {
387 _mesa_error(ctx, GL_INVALID_OPERATION,
388 "glTexParameter(swizzle 0x%x)", params[0]);
389 return GL_FALSE;
390 }
391 ASSERT(comp < 4);
392 if (swz >= 0) {
393 flush(ctx, texObj);
394 texObj->Swizzle[comp] = params[0];
395 set_swizzle_component(&texObj->_Swizzle, comp, swz);
396 return GL_TRUE;
397 }
398 }
399 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
400 return GL_FALSE;
401
402 case GL_TEXTURE_SWIZZLE_RGBA_EXT:
403 if (ctx->Extensions.EXT_texture_swizzle) {
404 GLuint comp;
405 flush(ctx, texObj);
406 for (comp = 0; comp < 4; comp++) {
407 const GLint swz = comp_to_swizzle(params[comp]);
408 if (swz >= 0) {
409 texObj->Swizzle[comp] = params[comp];
410 set_swizzle_component(&texObj->_Swizzle, comp, swz);
411 }
412 else {
413 _mesa_error(ctx, GL_INVALID_OPERATION,
414 "glTexParameter(swizzle 0x%x)", params[comp]);
415 return GL_FALSE;
416 }
417 }
418 return GL_TRUE;
419 }
420 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
421 return GL_FALSE;
422
423 default:
424 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
425 }
426 return GL_FALSE;
427 }
428
429
430 /**
431 * Set a float-valued texture parameter
432 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
433 */
434 static GLboolean
435 set_tex_parameterf(GLcontext *ctx,
436 struct gl_texture_object *texObj,
437 GLenum pname, const GLfloat *params)
438 {
439 switch (pname) {
440 case GL_TEXTURE_MIN_LOD:
441 if (texObj->MinLod == params[0])
442 return GL_FALSE;
443 flush(ctx, texObj);
444 texObj->MinLod = params[0];
445 return GL_TRUE;
446
447 case GL_TEXTURE_MAX_LOD:
448 if (texObj->MaxLod == params[0])
449 return GL_FALSE;
450 flush(ctx, texObj);
451 texObj->MaxLod = params[0];
452 return GL_TRUE;
453
454 case GL_TEXTURE_PRIORITY:
455 flush(ctx, texObj);
456 texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
457 return GL_TRUE;
458
459 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
460 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
461 if (texObj->MaxAnisotropy == params[0])
462 return GL_FALSE;
463 if (params[0] < 1.0) {
464 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
465 return GL_FALSE;
466 }
467 flush(ctx, texObj);
468 /* clamp to max, that's what NVIDIA does */
469 texObj->MaxAnisotropy = MIN2(params[0],
470 ctx->Const.MaxTextureMaxAnisotropy);
471 return GL_TRUE;
472 }
473 else {
474 static GLuint count = 0;
475 if (count++ < 10)
476 _mesa_error(ctx, GL_INVALID_ENUM,
477 "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
478 }
479 return GL_FALSE;
480
481 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
482 if (ctx->Extensions.ARB_shadow_ambient) {
483 if (texObj->CompareFailValue != params[0]) {
484 flush(ctx, texObj);
485 texObj->CompareFailValue = CLAMP(params[0], 0.0F, 1.0F);
486 return GL_TRUE;
487 }
488 }
489 else {
490 _mesa_error(ctx, GL_INVALID_ENUM,
491 "glTexParameter(pname=GL_TEXTURE_COMPARE_FAIL_VALUE_ARB)");
492 }
493 return GL_FALSE;
494
495 case GL_TEXTURE_LOD_BIAS:
496 /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias */
497 if (ctx->Extensions.EXT_texture_lod_bias) {
498 if (texObj->LodBias != params[0]) {
499 flush(ctx, texObj);
500 texObj->LodBias = params[0];
501 return GL_TRUE;
502 }
503 return GL_FALSE;
504 }
505 break;
506
507 case GL_TEXTURE_BORDER_COLOR:
508 flush(ctx, texObj);
509 texObj->BorderColor[RCOMP] = params[0];
510 texObj->BorderColor[GCOMP] = params[1];
511 texObj->BorderColor[BCOMP] = params[2];
512 texObj->BorderColor[ACOMP] = params[3];
513 return GL_TRUE;
514
515 default:
516 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
517 }
518 return GL_FALSE;
519 }
520
521
522 void GLAPIENTRY
523 _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
524 {
525 GLboolean need_update;
526 struct gl_texture_object *texObj;
527 GET_CURRENT_CONTEXT(ctx);
528 ASSERT_OUTSIDE_BEGIN_END(ctx);
529
530 texObj = get_texobj(ctx, target);
531 if (!texObj)
532 return;
533
534 switch (pname) {
535 case GL_TEXTURE_MIN_FILTER:
536 case GL_TEXTURE_MAG_FILTER:
537 case GL_TEXTURE_WRAP_S:
538 case GL_TEXTURE_WRAP_T:
539 case GL_TEXTURE_WRAP_R:
540 case GL_TEXTURE_BASE_LEVEL:
541 case GL_TEXTURE_MAX_LEVEL:
542 case GL_GENERATE_MIPMAP_SGIS:
543 case GL_TEXTURE_COMPARE_MODE_ARB:
544 case GL_TEXTURE_COMPARE_FUNC_ARB:
545 case GL_DEPTH_TEXTURE_MODE_ARB:
546 {
547 /* convert float param to int */
548 GLint p = (GLint) param;
549 need_update = set_tex_parameteri(ctx, texObj, pname, &p);
550 }
551 break;
552 default:
553 /* this will generate an error if pname is illegal */
554 need_update = set_tex_parameterf(ctx, texObj, pname, &param);
555 }
556
557 if (ctx->Driver.TexParameter && need_update) {
558 ctx->Driver.TexParameter(ctx, target, texObj, pname, &param);
559 }
560 }
561
562
563 void GLAPIENTRY
564 _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
565 {
566 GLboolean need_update;
567 struct gl_texture_object *texObj;
568 GET_CURRENT_CONTEXT(ctx);
569 ASSERT_OUTSIDE_BEGIN_END(ctx);
570
571 texObj = get_texobj(ctx, target);
572 if (!texObj)
573 return;
574
575 switch (pname) {
576 case GL_TEXTURE_MIN_FILTER:
577 case GL_TEXTURE_MAG_FILTER:
578 case GL_TEXTURE_WRAP_S:
579 case GL_TEXTURE_WRAP_T:
580 case GL_TEXTURE_WRAP_R:
581 case GL_TEXTURE_BASE_LEVEL:
582 case GL_TEXTURE_MAX_LEVEL:
583 case GL_GENERATE_MIPMAP_SGIS:
584 case GL_TEXTURE_COMPARE_MODE_ARB:
585 case GL_TEXTURE_COMPARE_FUNC_ARB:
586 case GL_DEPTH_TEXTURE_MODE_ARB:
587 {
588 /* convert float param to int */
589 GLint p = (GLint) params[0];
590 need_update = set_tex_parameteri(ctx, texObj, pname, &p);
591 }
592 break;
593
594 #ifdef FEATURE_OES_draw_texture
595 case GL_TEXTURE_CROP_RECT_OES:
596 {
597 /* convert float params to int */
598 GLint iparams[4];
599 iparams[0] = (GLint) params[0];
600 iparams[1] = (GLint) params[1];
601 iparams[2] = (GLint) params[2];
602 iparams[3] = (GLint) params[3];
603 need_update = set_tex_parameteri(ctx, target, iparams);
604 }
605 break;
606 #endif
607
608 default:
609 /* this will generate an error if pname is illegal */
610 need_update = set_tex_parameterf(ctx, texObj, pname, params);
611 }
612
613 if (ctx->Driver.TexParameter && need_update) {
614 ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
615 }
616 }
617
618
619 void GLAPIENTRY
620 _mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
621 {
622 GLboolean need_update;
623 struct gl_texture_object *texObj;
624 GET_CURRENT_CONTEXT(ctx);
625 ASSERT_OUTSIDE_BEGIN_END(ctx);
626
627 texObj = get_texobj(ctx, target);
628 if (!texObj)
629 return;
630
631 switch (pname) {
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 GLfloat fparam = (GLfloat) param;
640 /* convert int param to float */
641 need_update = set_tex_parameterf(ctx, texObj, pname, &fparam);
642 }
643 break;
644 default:
645 /* this will generate an error if pname is illegal */
646 need_update = set_tex_parameteri(ctx, texObj, pname, &param);
647 }
648
649 if (ctx->Driver.TexParameter && need_update) {
650 GLfloat fparam = (GLfloat) param;
651 ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam);
652 }
653 }
654
655
656 void GLAPIENTRY
657 _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
658 {
659 GLboolean need_update;
660 struct gl_texture_object *texObj;
661 GET_CURRENT_CONTEXT(ctx);
662 ASSERT_OUTSIDE_BEGIN_END(ctx);
663
664 texObj = get_texobj(ctx, target);
665 if (!texObj)
666 return;
667
668 switch (pname) {
669 case GL_TEXTURE_BORDER_COLOR:
670 {
671 /* convert int params to float */
672 GLfloat fparams[4];
673 fparams[0] = INT_TO_FLOAT(params[0]);
674 fparams[1] = INT_TO_FLOAT(params[1]);
675 fparams[2] = INT_TO_FLOAT(params[2]);
676 fparams[3] = INT_TO_FLOAT(params[3]);
677 need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
678 }
679 break;
680 case GL_TEXTURE_MIN_LOD:
681 case GL_TEXTURE_MAX_LOD:
682 case GL_TEXTURE_PRIORITY:
683 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
684 case GL_TEXTURE_LOD_BIAS:
685 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
686 {
687 /* convert int param to float */
688 GLfloat fparam = (GLfloat) params[0];
689 need_update = set_tex_parameterf(ctx, texObj, pname, &fparam);
690 }
691 break;
692 default:
693 /* this will generate an error if pname is illegal */
694 need_update = set_tex_parameteri(ctx, texObj, pname, params);
695 }
696
697 if (ctx->Driver.TexParameter && need_update) {
698 GLfloat fparams[4];
699 fparams[0] = INT_TO_FLOAT(params[0]);
700 if (pname == GL_TEXTURE_BORDER_COLOR ||
701 pname == GL_TEXTURE_CROP_RECT_OES) {
702 fparams[1] = INT_TO_FLOAT(params[1]);
703 fparams[2] = INT_TO_FLOAT(params[2]);
704 fparams[3] = INT_TO_FLOAT(params[3]);
705 }
706 ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams);
707 }
708 }
709
710
711 void GLAPIENTRY
712 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
713 GLenum pname, GLfloat *params )
714 {
715 GLint iparam;
716 _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
717 *params = (GLfloat) iparam;
718 }
719
720
721 void GLAPIENTRY
722 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
723 GLenum pname, GLint *params )
724 {
725 const struct gl_texture_unit *texUnit;
726 struct gl_texture_object *texObj;
727 const struct gl_texture_image *img = NULL;
728 GLboolean isProxy;
729 GLint maxLevels;
730 GET_CURRENT_CONTEXT(ctx);
731 ASSERT_OUTSIDE_BEGIN_END(ctx);
732
733 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
734 _mesa_error(ctx, GL_INVALID_OPERATION,
735 "glGetTexLevelParameteriv(current unit)");
736 return;
737 }
738
739 texUnit = _mesa_get_current_tex_unit(ctx);
740
741 /* this will catch bad target values */
742 maxLevels = _mesa_max_texture_levels(ctx, target);
743 if (maxLevels == 0) {
744 _mesa_error(ctx, GL_INVALID_ENUM,
745 "glGetTexLevelParameter[if]v(target=0x%x)", target);
746 return;
747 }
748
749 if (level < 0 || level >= maxLevels) {
750 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
751 return;
752 }
753
754 texObj = _mesa_select_tex_object(ctx, texUnit, target);
755 _mesa_lock_texture(ctx, texObj);
756
757 img = _mesa_select_tex_image(ctx, texObj, target, level);
758 if (!img || !img->TexFormat) {
759 /* undefined texture image */
760 if (pname == GL_TEXTURE_COMPONENTS)
761 *params = 1;
762 else
763 *params = 0;
764 goto out;
765 }
766
767 isProxy = _mesa_is_proxy_texture(target);
768
769 switch (pname) {
770 case GL_TEXTURE_WIDTH:
771 *params = img->Width;
772 break;
773 case GL_TEXTURE_HEIGHT:
774 *params = img->Height;
775 break;
776 case GL_TEXTURE_DEPTH:
777 *params = img->Depth;
778 break;
779 case GL_TEXTURE_INTERNAL_FORMAT:
780 *params = img->InternalFormat;
781 break;
782 case GL_TEXTURE_BORDER:
783 *params = img->Border;
784 break;
785 case GL_TEXTURE_RED_SIZE:
786 case GL_TEXTURE_GREEN_SIZE:
787 case GL_TEXTURE_BLUE_SIZE:
788 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
789 *params = _mesa_get_format_bits(img->TexFormat->MesaFormat, pname);
790 else
791 *params = 0;
792 break;
793 case GL_TEXTURE_ALPHA_SIZE:
794 if (img->_BaseFormat == GL_ALPHA ||
795 img->_BaseFormat == GL_LUMINANCE_ALPHA ||
796 img->_BaseFormat == GL_RGBA)
797 *params = _mesa_get_format_bits(img->TexFormat->MesaFormat, pname);
798 else
799 *params = 0;
800 break;
801 case GL_TEXTURE_INTENSITY_SIZE:
802 if (img->_BaseFormat != GL_INTENSITY)
803 *params = 0;
804 else {
805 *params = _mesa_get_format_bits(img->TexFormat->MesaFormat, pname);
806 if (*params == 0) {
807 /* intensity probably stored as rgb texture */
808 *params = MIN2(_mesa_get_format_bits(img->TexFormat->MesaFormat, GL_TEXTURE_RED_SIZE),
809 _mesa_get_format_bits(img->TexFormat->MesaFormat, GL_TEXTURE_GREEN_SIZE));
810 }
811 }
812 break;
813 case GL_TEXTURE_LUMINANCE_SIZE:
814 if (img->_BaseFormat != GL_LUMINANCE &&
815 img->_BaseFormat != GL_LUMINANCE_ALPHA)
816 *params = 0;
817 else {
818 *params = _mesa_get_format_bits(img->TexFormat->MesaFormat, pname);
819 if (img->TexFormat->LuminanceBits == 0) {
820 /* luminance probably stored as rgb texture */
821 *params = MIN2(_mesa_get_format_bits(img->TexFormat->MesaFormat, GL_TEXTURE_RED_SIZE),
822 _mesa_get_format_bits(img->TexFormat->MesaFormat, GL_TEXTURE_GREEN_SIZE));
823 }
824 }
825 break;
826 case GL_TEXTURE_INDEX_SIZE_EXT:
827 if (img->_BaseFormat == GL_COLOR_INDEX)
828 *params = _mesa_get_format_bits(img->TexFormat->MesaFormat, pname);
829 else
830 *params = 0;
831 break;
832 case GL_TEXTURE_DEPTH_SIZE_ARB:
833 if (ctx->Extensions.ARB_depth_texture)
834 *params = _mesa_get_format_bits(img->TexFormat->MesaFormat, pname);
835 else
836 _mesa_error(ctx, GL_INVALID_ENUM,
837 "glGetTexLevelParameter[if]v(pname)");
838 break;
839 case GL_TEXTURE_STENCIL_SIZE_EXT:
840 if (ctx->Extensions.EXT_packed_depth_stencil ||
841 ctx->Extensions.ARB_framebuffer_object) {
842 *params = _mesa_get_format_bits(img->TexFormat->MesaFormat, pname);
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 = _mesa_get_current_tex_unit(ctx);
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 = _mesa_get_current_tex_unit(ctx);
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 }