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