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