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