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