mesa: add support for GL_OES_EGL_image_external
[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
888
889 void GLAPIENTRY
890 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
891 GLenum pname, GLfloat *params )
892 {
893 GLint iparam;
894 _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
895 *params = (GLfloat) iparam;
896 }
897
898
899 void GLAPIENTRY
900 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
901 GLenum pname, GLint *params )
902 {
903 const struct gl_texture_unit *texUnit;
904 struct gl_texture_object *texObj;
905 const struct gl_texture_image *img = NULL;
906 GLint maxLevels;
907 gl_format texFormat;
908 GET_CURRENT_CONTEXT(ctx);
909 ASSERT_OUTSIDE_BEGIN_END(ctx);
910
911 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
912 _mesa_error(ctx, GL_INVALID_OPERATION,
913 "glGetTexLevelParameteriv(current unit)");
914 return;
915 }
916
917 texUnit = _mesa_get_current_tex_unit(ctx);
918
919 /* this will catch bad target values */
920 maxLevels = _mesa_max_texture_levels(ctx, target);
921 if (maxLevels == 0) {
922 _mesa_error(ctx, GL_INVALID_ENUM,
923 "glGetTexLevelParameter[if]v(target=0x%x)", target);
924 return;
925 }
926
927 if (level < 0 || level >= maxLevels) {
928 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
929 return;
930 }
931
932 texObj = _mesa_select_tex_object(ctx, texUnit, target);
933
934 img = _mesa_select_tex_image(ctx, texObj, target, level);
935 if (!img || img->TexFormat == MESA_FORMAT_NONE) {
936 /* undefined texture image */
937 if (pname == GL_TEXTURE_COMPONENTS)
938 *params = 1;
939 else
940 *params = 0;
941 return;
942 }
943
944 texFormat = img->TexFormat;
945
946 switch (pname) {
947 case GL_TEXTURE_WIDTH:
948 *params = img->Width;
949 break;
950 case GL_TEXTURE_HEIGHT:
951 *params = img->Height;
952 break;
953 case GL_TEXTURE_DEPTH:
954 *params = img->Depth;
955 break;
956 case GL_TEXTURE_INTERNAL_FORMAT:
957 if (_mesa_is_format_compressed(texFormat)) {
958 /* need to return the actual compressed format */
959 *params = _mesa_compressed_format_to_glenum(ctx, texFormat);
960 }
961 else {
962 /* If the true internal format is not compressed but the user
963 * requested a generic compressed format, we have to return the
964 * generic base format that matches.
965 *
966 * From page 119 (page 129 of the PDF) of the OpenGL 1.3 spec:
967 *
968 * "If no specific compressed format is available,
969 * internalformat is instead replaced by the corresponding base
970 * internal format."
971 *
972 * Otherwise just return the user's requested internal format
973 */
974 const GLenum f =
975 _mesa_gl_compressed_format_base_format(img->InternalFormat);
976
977 *params = (f != 0) ? f : img->InternalFormat;
978 }
979 break;
980 case GL_TEXTURE_BORDER:
981 *params = img->Border;
982 break;
983 case GL_TEXTURE_RED_SIZE:
984 if (img->_BaseFormat == GL_RED) {
985 *params = _mesa_get_format_bits(texFormat, pname);
986 break;
987 }
988 /* FALLTHROUGH */
989 case GL_TEXTURE_GREEN_SIZE:
990 if (img->_BaseFormat == GL_RG) {
991 *params = _mesa_get_format_bits(texFormat, pname);
992 break;
993 }
994 /* FALLTHROUGH */
995 case GL_TEXTURE_BLUE_SIZE:
996 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
997 *params = _mesa_get_format_bits(texFormat, pname);
998 else
999 *params = 0;
1000 break;
1001 case GL_TEXTURE_ALPHA_SIZE:
1002 if (img->_BaseFormat == GL_ALPHA ||
1003 img->_BaseFormat == GL_LUMINANCE_ALPHA ||
1004 img->_BaseFormat == GL_RGBA)
1005 *params = _mesa_get_format_bits(texFormat, pname);
1006 else
1007 *params = 0;
1008 break;
1009 case GL_TEXTURE_INTENSITY_SIZE:
1010 if (img->_BaseFormat != GL_INTENSITY)
1011 *params = 0;
1012 else {
1013 *params = _mesa_get_format_bits(texFormat, pname);
1014 if (*params == 0) {
1015 /* intensity probably stored as rgb texture */
1016 *params = MIN2(_mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE),
1017 _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE));
1018 }
1019 }
1020 break;
1021 case GL_TEXTURE_LUMINANCE_SIZE:
1022 if (img->_BaseFormat != GL_LUMINANCE &&
1023 img->_BaseFormat != GL_LUMINANCE_ALPHA)
1024 *params = 0;
1025 else {
1026 *params = _mesa_get_format_bits(texFormat, pname);
1027 if (*params == 0) {
1028 /* luminance probably stored as rgb texture */
1029 *params = MIN2(_mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE),
1030 _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE));
1031 }
1032 }
1033 break;
1034 case GL_TEXTURE_DEPTH_SIZE_ARB:
1035 if (!ctx->Extensions.ARB_depth_texture)
1036 goto invalid_pname;
1037 *params = _mesa_get_format_bits(texFormat, pname);
1038 break;
1039 case GL_TEXTURE_STENCIL_SIZE_EXT:
1040 if (!ctx->Extensions.EXT_packed_depth_stencil &&
1041 !ctx->Extensions.ARB_framebuffer_object)
1042 goto invalid_pname;
1043 *params = _mesa_get_format_bits(texFormat, pname);
1044 break;
1045 case GL_TEXTURE_SHARED_SIZE:
1046 if (ctx->VersionMajor < 3 &&
1047 !ctx->Extensions.EXT_texture_shared_exponent)
1048 goto invalid_pname;
1049 *params = texFormat == MESA_FORMAT_RGB9_E5_FLOAT ? 5 : 0;
1050 break;
1051
1052 /* GL_ARB_texture_compression */
1053 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
1054 if (_mesa_is_format_compressed(texFormat) &&
1055 !_mesa_is_proxy_texture(target)) {
1056 *params = _mesa_format_image_size(texFormat, img->Width,
1057 img->Height, img->Depth);
1058 }
1059 else {
1060 _mesa_error(ctx, GL_INVALID_OPERATION,
1061 "glGetTexLevelParameter[if]v(pname)");
1062 }
1063 break;
1064 case GL_TEXTURE_COMPRESSED:
1065 *params = (GLint) _mesa_is_format_compressed(texFormat);
1066 break;
1067
1068 /* GL_ARB_texture_float */
1069 case GL_TEXTURE_RED_TYPE_ARB:
1070 if (!ctx->Extensions.ARB_texture_float)
1071 goto invalid_pname;
1072 *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE) ?
1073 _mesa_get_format_datatype(texFormat) : GL_NONE;
1074 break;
1075 case GL_TEXTURE_GREEN_TYPE_ARB:
1076 if (!ctx->Extensions.ARB_texture_float)
1077 goto invalid_pname;
1078 *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE) ?
1079 _mesa_get_format_datatype(texFormat) : GL_NONE;
1080 break;
1081 case GL_TEXTURE_BLUE_TYPE_ARB:
1082 if (!ctx->Extensions.ARB_texture_float)
1083 goto invalid_pname;
1084 *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_BLUE_SIZE) ?
1085 _mesa_get_format_datatype(texFormat) : GL_NONE;
1086 break;
1087 case GL_TEXTURE_ALPHA_TYPE_ARB:
1088 if (!ctx->Extensions.ARB_texture_float)
1089 goto invalid_pname;
1090 *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_ALPHA_SIZE) ?
1091 _mesa_get_format_datatype(texFormat) : GL_NONE;
1092 break;
1093 case GL_TEXTURE_LUMINANCE_TYPE_ARB:
1094 if (!ctx->Extensions.ARB_texture_float)
1095 goto invalid_pname;
1096 *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_LUMINANCE_SIZE) ?
1097 _mesa_get_format_datatype(texFormat) : GL_NONE;
1098 break;
1099 case GL_TEXTURE_INTENSITY_TYPE_ARB:
1100 if (!ctx->Extensions.ARB_texture_float)
1101 goto invalid_pname;
1102 *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_INTENSITY_SIZE) ?
1103 _mesa_get_format_datatype(texFormat) : GL_NONE;
1104 break;
1105 case GL_TEXTURE_DEPTH_TYPE_ARB:
1106 if (!ctx->Extensions.ARB_texture_float)
1107 goto invalid_pname;
1108 *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_DEPTH_SIZE) ?
1109 _mesa_get_format_datatype(texFormat) : GL_NONE;
1110 break;
1111
1112 default:
1113 goto invalid_pname;
1114 }
1115
1116 /* no error if we get here */
1117 return;
1118
1119 invalid_pname:
1120 _mesa_error(ctx, GL_INVALID_ENUM,
1121 "glGetTexLevelParameter[if]v(pname=%s)",
1122 _mesa_lookup_enum_by_nr(pname));
1123 }
1124
1125
1126
1127 void GLAPIENTRY
1128 _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
1129 {
1130 struct gl_texture_object *obj;
1131 GET_CURRENT_CONTEXT(ctx);
1132 ASSERT_OUTSIDE_BEGIN_END(ctx);
1133
1134 obj = get_texobj(ctx, target, GL_TRUE);
1135 if (!obj)
1136 return;
1137
1138 _mesa_lock_texture(ctx, obj);
1139 switch (pname) {
1140 case GL_TEXTURE_MAG_FILTER:
1141 *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter);
1142 break;
1143 case GL_TEXTURE_MIN_FILTER:
1144 *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter);
1145 break;
1146 case GL_TEXTURE_WRAP_S:
1147 *params = ENUM_TO_FLOAT(obj->Sampler.WrapS);
1148 break;
1149 case GL_TEXTURE_WRAP_T:
1150 *params = ENUM_TO_FLOAT(obj->Sampler.WrapT);
1151 break;
1152 case GL_TEXTURE_WRAP_R:
1153 *params = ENUM_TO_FLOAT(obj->Sampler.WrapR);
1154 break;
1155 case GL_TEXTURE_BORDER_COLOR:
1156 if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
1157 _mesa_update_state_locked(ctx);
1158 if (ctx->Color._ClampFragmentColor) {
1159 params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
1160 params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
1161 params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
1162 params[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
1163 }
1164 else {
1165 params[0] = obj->Sampler.BorderColor.f[0];
1166 params[1] = obj->Sampler.BorderColor.f[1];
1167 params[2] = obj->Sampler.BorderColor.f[2];
1168 params[3] = obj->Sampler.BorderColor.f[3];
1169 }
1170 break;
1171 case GL_TEXTURE_RESIDENT:
1172 *params = ctx->Driver.IsTextureResident ?
1173 ctx->Driver.IsTextureResident(ctx, obj) : 1.0F;
1174 break;
1175 case GL_TEXTURE_PRIORITY:
1176 *params = obj->Priority;
1177 break;
1178 case GL_TEXTURE_MIN_LOD:
1179 *params = obj->Sampler.MinLod;
1180 break;
1181 case GL_TEXTURE_MAX_LOD:
1182 *params = obj->Sampler.MaxLod;
1183 break;
1184 case GL_TEXTURE_BASE_LEVEL:
1185 *params = (GLfloat) obj->BaseLevel;
1186 break;
1187 case GL_TEXTURE_MAX_LEVEL:
1188 *params = (GLfloat) obj->MaxLevel;
1189 break;
1190 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1191 if (!ctx->Extensions.EXT_texture_filter_anisotropic)
1192 goto invalid_pname;
1193 *params = obj->Sampler.MaxAnisotropy;
1194 break;
1195 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
1196 if (!ctx->Extensions.ARB_shadow_ambient)
1197 goto invalid_pname;
1198 *params = obj->Sampler.CompareFailValue;
1199 break;
1200 case GL_GENERATE_MIPMAP_SGIS:
1201 *params = (GLfloat) obj->GenerateMipmap;
1202 break;
1203 case GL_TEXTURE_COMPARE_MODE_ARB:
1204 if (!ctx->Extensions.ARB_shadow)
1205 goto invalid_pname;
1206 *params = (GLfloat) obj->Sampler.CompareMode;
1207 break;
1208 case GL_TEXTURE_COMPARE_FUNC_ARB:
1209 if (!ctx->Extensions.ARB_shadow)
1210 goto invalid_pname;
1211 *params = (GLfloat) obj->Sampler.CompareFunc;
1212 break;
1213 case GL_DEPTH_TEXTURE_MODE_ARB:
1214 if (!ctx->Extensions.ARB_depth_texture)
1215 goto invalid_pname;
1216 *params = (GLfloat) obj->Sampler.DepthMode;
1217 break;
1218 case GL_TEXTURE_LOD_BIAS:
1219 *params = obj->Sampler.LodBias;
1220 break;
1221 #if FEATURE_OES_draw_texture
1222 case GL_TEXTURE_CROP_RECT_OES:
1223 params[0] = obj->CropRect[0];
1224 params[1] = obj->CropRect[1];
1225 params[2] = obj->CropRect[2];
1226 params[3] = obj->CropRect[3];
1227 break;
1228 #endif
1229
1230 case GL_TEXTURE_SWIZZLE_R_EXT:
1231 case GL_TEXTURE_SWIZZLE_G_EXT:
1232 case GL_TEXTURE_SWIZZLE_B_EXT:
1233 case GL_TEXTURE_SWIZZLE_A_EXT:
1234 if (!ctx->Extensions.EXT_texture_swizzle)
1235 goto invalid_pname;
1236 *params = (GLfloat) obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
1237 break;
1238
1239 case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1240 if (!ctx->Extensions.EXT_texture_swizzle) {
1241 goto invalid_pname;
1242 }
1243 else {
1244 GLuint comp;
1245 for (comp = 0; comp < 4; comp++) {
1246 params[comp] = (GLfloat) obj->Swizzle[comp];
1247 }
1248 }
1249 break;
1250
1251 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1252 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
1253 goto invalid_pname;
1254 *params = (GLfloat) obj->Sampler.CubeMapSeamless;
1255 break;
1256
1257 case GL_TEXTURE_IMMUTABLE_FORMAT:
1258 if (!ctx->Extensions.ARB_texture_storage)
1259 goto invalid_pname;
1260 *params = (GLfloat) obj->Immutable;
1261 break;
1262
1263 default:
1264 goto invalid_pname;
1265 }
1266
1267 /* no error if we get here */
1268 _mesa_unlock_texture(ctx, obj);
1269 return;
1270
1271 invalid_pname:
1272 _mesa_unlock_texture(ctx, obj);
1273 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", pname);
1274 }
1275
1276
1277 void GLAPIENTRY
1278 _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
1279 {
1280 struct gl_texture_object *obj;
1281 GET_CURRENT_CONTEXT(ctx);
1282 ASSERT_OUTSIDE_BEGIN_END(ctx);
1283
1284 obj = get_texobj(ctx, target, GL_TRUE);
1285 if (!obj)
1286 return;
1287
1288 _mesa_lock_texture(ctx, obj);
1289 switch (pname) {
1290 case GL_TEXTURE_MAG_FILTER:
1291 *params = (GLint) obj->Sampler.MagFilter;
1292 break;;
1293 case GL_TEXTURE_MIN_FILTER:
1294 *params = (GLint) obj->Sampler.MinFilter;
1295 break;;
1296 case GL_TEXTURE_WRAP_S:
1297 *params = (GLint) obj->Sampler.WrapS;
1298 break;;
1299 case GL_TEXTURE_WRAP_T:
1300 *params = (GLint) obj->Sampler.WrapT;
1301 break;;
1302 case GL_TEXTURE_WRAP_R:
1303 *params = (GLint) obj->Sampler.WrapR;
1304 break;;
1305 case GL_TEXTURE_BORDER_COLOR:
1306 {
1307 GLfloat b[4];
1308 b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
1309 b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
1310 b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
1311 b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
1312 params[0] = FLOAT_TO_INT(b[0]);
1313 params[1] = FLOAT_TO_INT(b[1]);
1314 params[2] = FLOAT_TO_INT(b[2]);
1315 params[3] = FLOAT_TO_INT(b[3]);
1316 }
1317 break;;
1318 case GL_TEXTURE_RESIDENT:
1319 *params = ctx->Driver.IsTextureResident ?
1320 ctx->Driver.IsTextureResident(ctx, obj) : 1;
1321 break;;
1322 case GL_TEXTURE_PRIORITY:
1323 *params = FLOAT_TO_INT(obj->Priority);
1324 break;;
1325 case GL_TEXTURE_MIN_LOD:
1326 *params = (GLint) obj->Sampler.MinLod;
1327 break;;
1328 case GL_TEXTURE_MAX_LOD:
1329 *params = (GLint) obj->Sampler.MaxLod;
1330 break;;
1331 case GL_TEXTURE_BASE_LEVEL:
1332 *params = obj->BaseLevel;
1333 break;;
1334 case GL_TEXTURE_MAX_LEVEL:
1335 *params = obj->MaxLevel;
1336 break;;
1337 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1338 if (!ctx->Extensions.EXT_texture_filter_anisotropic)
1339 goto invalid_pname;
1340 *params = (GLint) obj->Sampler.MaxAnisotropy;
1341 break;
1342 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
1343 if (!ctx->Extensions.ARB_shadow_ambient)
1344 goto invalid_pname;
1345 *params = (GLint) FLOAT_TO_INT(obj->Sampler.CompareFailValue);
1346 break;
1347 case GL_GENERATE_MIPMAP_SGIS:
1348 *params = (GLint) obj->GenerateMipmap;
1349 break;
1350 case GL_TEXTURE_COMPARE_MODE_ARB:
1351 if (!ctx->Extensions.ARB_shadow)
1352 goto invalid_pname;
1353 *params = (GLint) obj->Sampler.CompareMode;
1354 break;
1355 case GL_TEXTURE_COMPARE_FUNC_ARB:
1356 if (!ctx->Extensions.ARB_shadow)
1357 goto invalid_pname;
1358 *params = (GLint) obj->Sampler.CompareFunc;
1359 break;
1360 case GL_DEPTH_TEXTURE_MODE_ARB:
1361 if (!ctx->Extensions.ARB_depth_texture)
1362 goto invalid_pname;
1363 *params = (GLint) obj->Sampler.DepthMode;
1364 break;
1365 case GL_TEXTURE_LOD_BIAS:
1366 *params = (GLint) obj->Sampler.LodBias;
1367 break;
1368 #if FEATURE_OES_draw_texture
1369 case GL_TEXTURE_CROP_RECT_OES:
1370 params[0] = obj->CropRect[0];
1371 params[1] = obj->CropRect[1];
1372 params[2] = obj->CropRect[2];
1373 params[3] = obj->CropRect[3];
1374 break;
1375 #endif
1376 case GL_TEXTURE_SWIZZLE_R_EXT:
1377 case GL_TEXTURE_SWIZZLE_G_EXT:
1378 case GL_TEXTURE_SWIZZLE_B_EXT:
1379 case GL_TEXTURE_SWIZZLE_A_EXT:
1380 if (!ctx->Extensions.EXT_texture_swizzle)
1381 goto invalid_pname;
1382 *params = obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
1383 break;
1384
1385 case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1386 if (!ctx->Extensions.EXT_texture_swizzle)
1387 goto invalid_pname;
1388 COPY_4V(params, obj->Swizzle);
1389 break;
1390
1391 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1392 if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
1393 goto invalid_pname;
1394 *params = (GLint) obj->Sampler.CubeMapSeamless;
1395 break;
1396
1397 case GL_TEXTURE_IMMUTABLE_FORMAT:
1398 if (!ctx->Extensions.ARB_texture_storage)
1399 goto invalid_pname;
1400 *params = (GLint) obj->Immutable;
1401 break;
1402
1403 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
1404 if (!ctx->Extensions.OES_EGL_image_external)
1405 goto invalid_pname;
1406 *params = obj->RequiredTextureImageUnits;
1407 break;
1408
1409 default:
1410 goto invalid_pname;
1411 }
1412
1413 /* no error if we get here */
1414 _mesa_unlock_texture(ctx, obj);
1415 return;
1416
1417 invalid_pname:
1418 _mesa_unlock_texture(ctx, obj);
1419 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname);
1420 }
1421
1422
1423 /** New in GL 3.0 */
1424 void GLAPIENTRY
1425 _mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
1426 {
1427 struct gl_texture_object *texObj;
1428 GET_CURRENT_CONTEXT(ctx);
1429 ASSERT_OUTSIDE_BEGIN_END(ctx);
1430
1431 texObj = get_texobj(ctx, target, GL_TRUE);
1432 if (!texObj)
1433 return;
1434
1435 switch (pname) {
1436 case GL_TEXTURE_BORDER_COLOR:
1437 COPY_4V(params, texObj->Sampler.BorderColor.i);
1438 break;
1439 default:
1440 _mesa_GetTexParameteriv(target, pname, params);
1441 }
1442 }
1443
1444
1445 /** New in GL 3.0 */
1446 void GLAPIENTRY
1447 _mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
1448 {
1449 struct gl_texture_object *texObj;
1450 GET_CURRENT_CONTEXT(ctx);
1451 ASSERT_OUTSIDE_BEGIN_END(ctx);
1452
1453 texObj = get_texobj(ctx, target, GL_TRUE);
1454 if (!texObj)
1455 return;
1456
1457 switch (pname) {
1458 case GL_TEXTURE_BORDER_COLOR:
1459 COPY_4V(params, texObj->Sampler.BorderColor.i);
1460 break;
1461 default:
1462 {
1463 GLint ip[4];
1464 _mesa_GetTexParameteriv(target, pname, ip);
1465 params[0] = ip[0];
1466 if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT ||
1467 pname == GL_TEXTURE_CROP_RECT_OES) {
1468 params[1] = ip[1];
1469 params[2] = ip[2];
1470 params[3] = ip[3];
1471 }
1472 }
1473 }
1474 }