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