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