[PROPSYS]
[reactos.git] / reactos / dll / opengl / 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 #include <precomp.h>
33
34 /**
35 * Check if a coordinate wrap mode is supported for the texture target.
36 * \return GL_TRUE if legal, GL_FALSE otherwise
37 */
38 static GLboolean
39 validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap)
40 {
41 switch (wrap) {
42 case GL_CLAMP:
43 case GL_REPEAT:
44 case GL_MIRRORED_REPEAT:
45 return GL_TRUE;
46 default:
47 break;
48 }
49
50 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap );
51 return GL_FALSE;
52 }
53
54
55 /**
56 * Get current texture object for given target.
57 * Return NULL if any error (and record the error).
58 * Note that this is different from _mesa_select_tex_object() in that proxy
59 * targets are not accepted.
60 * Only the glGetTexLevelParameter() functions accept proxy targets.
61 */
62 static struct gl_texture_object *
63 get_texobj(struct gl_context *ctx, GLenum target, GLboolean get)
64 {
65 struct gl_texture_unit *texUnit;
66
67 texUnit = &ctx->Texture.Unit;
68
69 switch (target) {
70 case GL_TEXTURE_1D:
71 return texUnit->CurrentTex[TEXTURE_1D_INDEX];
72 case GL_TEXTURE_2D:
73 return texUnit->CurrentTex[TEXTURE_2D_INDEX];
74 case GL_TEXTURE_3D:
75 return texUnit->CurrentTex[TEXTURE_3D_INDEX];
76 case GL_TEXTURE_CUBE_MAP:
77 if (ctx->Extensions.ARB_texture_cube_map) {
78 return texUnit->CurrentTex[TEXTURE_CUBE_INDEX];
79 }
80 break;
81 default:
82 ;
83 }
84
85 _mesa_error(ctx, GL_INVALID_ENUM,
86 "gl%sTexParameter(target)", get ? "Get" : "");
87 return NULL;
88 }
89
90
91 /**
92 * This is called just prior to changing any texture object state which
93 * will not effect texture completeness.
94 */
95 static inline void
96 flush(struct gl_context *ctx)
97 {
98 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
99 }
100
101
102 /**
103 * This is called just prior to changing any texture object state which
104 * can effect texture completeness (texture base level, max level,
105 * minification filter).
106 * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE
107 * state flag and then mark the texture object as 'incomplete' so that any
108 * per-texture derived state gets recomputed.
109 */
110 static inline void
111 incomplete(struct gl_context *ctx, struct gl_texture_object *texObj)
112 {
113 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
114 texObj->_Complete = GL_FALSE;
115 }
116
117
118 /**
119 * Set an integer-valued texture parameter
120 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
121 */
122 static GLboolean
123 set_tex_parameteri(struct gl_context *ctx,
124 struct gl_texture_object *texObj,
125 GLenum pname, const GLint *params)
126 {
127 switch (pname) {
128 case GL_TEXTURE_MIN_FILTER:
129 if (texObj->Sampler.MinFilter == params[0])
130 return GL_FALSE;
131 switch (params[0]) {
132 case GL_NEAREST:
133 case GL_LINEAR:
134 incomplete(ctx, texObj);
135 texObj->Sampler.MinFilter = params[0];
136 return GL_TRUE;
137 case GL_NEAREST_MIPMAP_NEAREST:
138 case GL_LINEAR_MIPMAP_NEAREST:
139 case GL_NEAREST_MIPMAP_LINEAR:
140 case GL_LINEAR_MIPMAP_LINEAR:
141 incomplete(ctx, texObj);
142 texObj->Sampler.MinFilter = params[0];
143 return GL_TRUE;
144 /* fall-through */
145 default:
146 goto invalid_param;
147 }
148 return GL_FALSE;
149
150 case GL_TEXTURE_MAG_FILTER:
151 if (texObj->Sampler.MagFilter == params[0])
152 return GL_FALSE;
153 switch (params[0]) {
154 case GL_NEAREST:
155 case GL_LINEAR:
156 flush(ctx); /* does not effect completeness */
157 texObj->Sampler.MagFilter = params[0];
158 return GL_TRUE;
159 default:
160 goto invalid_param;
161 }
162 return GL_FALSE;
163
164 case GL_TEXTURE_WRAP_S:
165 if (texObj->Sampler.WrapS == params[0])
166 return GL_FALSE;
167 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
168 flush(ctx);
169 texObj->Sampler.WrapS = params[0];
170 return GL_TRUE;
171 }
172 return GL_FALSE;
173
174 case GL_TEXTURE_WRAP_T:
175 if (texObj->Sampler.WrapT == params[0])
176 return GL_FALSE;
177 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
178 flush(ctx);
179 texObj->Sampler.WrapT = params[0];
180 return GL_TRUE;
181 }
182 return GL_FALSE;
183
184 case GL_TEXTURE_WRAP_R:
185 if (texObj->Sampler.WrapR == params[0])
186 return GL_FALSE;
187 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
188 flush(ctx);
189 texObj->Sampler.WrapR = params[0];
190 return GL_TRUE;
191 }
192 return GL_FALSE;
193
194 default:
195 goto invalid_pname;
196 }
197
198 invalid_pname:
199 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)",
200 _mesa_lookup_enum_by_nr(pname));
201 return GL_FALSE;
202
203 invalid_param:
204 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param=%s)",
205 _mesa_lookup_enum_by_nr(params[0]));
206 return GL_FALSE;
207 }
208
209
210 /**
211 * Set a float-valued texture parameter
212 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
213 */
214 static GLboolean
215 set_tex_parameterf(struct gl_context *ctx,
216 struct gl_texture_object *texObj,
217 GLenum pname, const GLfloat *params)
218 {
219 switch (pname) {
220
221 case GL_TEXTURE_PRIORITY:
222 flush(ctx);
223 texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
224 return GL_TRUE;
225
226 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
227 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
228 if (texObj->Sampler.MaxAnisotropy == params[0])
229 return GL_FALSE;
230 if (params[0] < 1.0) {
231 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
232 return GL_FALSE;
233 }
234 flush(ctx);
235 /* clamp to max, that's what NVIDIA does */
236 texObj->Sampler.MaxAnisotropy = MIN2(params[0],
237 ctx->Const.MaxTextureMaxAnisotropy);
238 return GL_TRUE;
239 }
240 else {
241 static GLuint count = 0;
242 if (count++ < 10)
243 _mesa_error(ctx, GL_INVALID_ENUM,
244 "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
245 }
246 return GL_FALSE;
247
248 case GL_TEXTURE_BORDER_COLOR:
249 flush(ctx);
250 /* ARB_texture_float disables clamping */
251 if (ctx->Extensions.ARB_texture_float) {
252 texObj->Sampler.BorderColor.f[RCOMP] = params[0];
253 texObj->Sampler.BorderColor.f[GCOMP] = params[1];
254 texObj->Sampler.BorderColor.f[BCOMP] = params[2];
255 texObj->Sampler.BorderColor.f[ACOMP] = params[3];
256 } else {
257 texObj->Sampler.BorderColor.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F);
258 texObj->Sampler.BorderColor.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F);
259 texObj->Sampler.BorderColor.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F);
260 texObj->Sampler.BorderColor.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F);
261 }
262 return GL_TRUE;
263
264 default:
265 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
266 }
267 return GL_FALSE;
268 }
269
270
271 void GLAPIENTRY
272 _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
273 {
274 GLboolean need_update;
275 struct gl_texture_object *texObj;
276 GET_CURRENT_CONTEXT(ctx);
277 ASSERT_OUTSIDE_BEGIN_END(ctx);
278
279 texObj = get_texobj(ctx, target, GL_FALSE);
280 if (!texObj)
281 return;
282
283 switch (pname) {
284 case GL_TEXTURE_MIN_FILTER:
285 case GL_TEXTURE_MAG_FILTER:
286 case GL_TEXTURE_WRAP_S:
287 case GL_TEXTURE_WRAP_T:
288 case GL_TEXTURE_WRAP_R:
289 case GL_TEXTURE_COMPARE_MODE_ARB:
290 case GL_TEXTURE_COMPARE_FUNC_ARB:
291 case GL_DEPTH_TEXTURE_MODE_ARB:
292 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
293 {
294 /* convert float param to int */
295 GLint p[4];
296 p[0] = (GLint) param;
297 p[1] = p[2] = p[3] = 0;
298 need_update = set_tex_parameteri(ctx, texObj, pname, p);
299 }
300 break;
301 case GL_TEXTURE_SWIZZLE_R_EXT:
302 case GL_TEXTURE_SWIZZLE_G_EXT:
303 case GL_TEXTURE_SWIZZLE_B_EXT:
304 case GL_TEXTURE_SWIZZLE_A_EXT:
305 {
306 GLint p[4];
307 p[0] = (GLint) param;
308 p[1] = p[2] = p[3] = 0;
309 need_update = set_tex_parameteri(ctx, texObj, pname, p);
310 }
311 break;
312 default:
313 {
314 /* this will generate an error if pname is illegal */
315 GLfloat p[4];
316 p[0] = param;
317 p[1] = p[2] = p[3] = 0.0F;
318 need_update = set_tex_parameterf(ctx, texObj, pname, p);
319 }
320 }
321
322 if (ctx->Driver.TexParameter && need_update) {
323 ctx->Driver.TexParameter(ctx, target, texObj, pname, &param);
324 }
325 }
326
327
328 void GLAPIENTRY
329 _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
330 {
331 GLboolean need_update;
332 struct gl_texture_object *texObj;
333 GET_CURRENT_CONTEXT(ctx);
334 ASSERT_OUTSIDE_BEGIN_END(ctx);
335
336 texObj = get_texobj(ctx, target, GL_FALSE);
337 if (!texObj)
338 return;
339
340 switch (pname) {
341 case GL_TEXTURE_MIN_FILTER:
342 case GL_TEXTURE_MAG_FILTER:
343 case GL_TEXTURE_WRAP_S:
344 case GL_TEXTURE_WRAP_T:
345 case GL_TEXTURE_WRAP_R:
346 case GL_TEXTURE_COMPARE_MODE_ARB:
347 case GL_TEXTURE_COMPARE_FUNC_ARB:
348 case GL_DEPTH_TEXTURE_MODE_ARB:
349 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
350 {
351 /* convert float param to int */
352 GLint p[4];
353 p[0] = (GLint) params[0];
354 p[1] = p[2] = p[3] = 0;
355 need_update = set_tex_parameteri(ctx, texObj, pname, p);
356 }
357 break;
358
359 case GL_TEXTURE_SWIZZLE_R_EXT:
360 case GL_TEXTURE_SWIZZLE_G_EXT:
361 case GL_TEXTURE_SWIZZLE_B_EXT:
362 case GL_TEXTURE_SWIZZLE_A_EXT:
363 case GL_TEXTURE_SWIZZLE_RGBA_EXT:
364 {
365 GLint p[4] = {0, 0, 0, 0};
366 p[0] = (GLint) params[0];
367 if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT) {
368 p[1] = (GLint) params[1];
369 p[2] = (GLint) params[2];
370 p[3] = (GLint) params[3];
371 }
372 need_update = set_tex_parameteri(ctx, texObj, pname, p);
373 }
374 break;
375 default:
376 /* this will generate an error if pname is illegal */
377 need_update = set_tex_parameterf(ctx, texObj, pname, params);
378 }
379
380 if (ctx->Driver.TexParameter && need_update) {
381 ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
382 }
383 }
384
385
386 void GLAPIENTRY
387 _mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
388 {
389 GLboolean need_update;
390 struct gl_texture_object *texObj;
391 GET_CURRENT_CONTEXT(ctx);
392 ASSERT_OUTSIDE_BEGIN_END(ctx);
393
394 texObj = get_texobj(ctx, target, GL_FALSE);
395 if (!texObj)
396 return;
397
398 switch (pname) {
399 case GL_TEXTURE_MIN_LOD:
400 case GL_TEXTURE_MAX_LOD:
401 case GL_TEXTURE_PRIORITY:
402 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
403 case GL_TEXTURE_LOD_BIAS:
404 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
405 {
406 GLfloat fparam[4];
407 fparam[0] = (GLfloat) param;
408 fparam[1] = fparam[2] = fparam[3] = 0.0F;
409 /* convert int param to float */
410 need_update = set_tex_parameterf(ctx, texObj, pname, fparam);
411 }
412 break;
413 default:
414 /* this will generate an error if pname is illegal */
415 {
416 GLint iparam[4];
417 iparam[0] = param;
418 iparam[1] = iparam[2] = iparam[3] = 0;
419 need_update = set_tex_parameteri(ctx, texObj, pname, iparam);
420 }
421 }
422
423 if (ctx->Driver.TexParameter && need_update) {
424 GLfloat fparam = (GLfloat) param;
425 ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam);
426 }
427 }
428
429
430 void GLAPIENTRY
431 _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
432 {
433 GLboolean need_update;
434 struct gl_texture_object *texObj;
435 GET_CURRENT_CONTEXT(ctx);
436 ASSERT_OUTSIDE_BEGIN_END(ctx);
437
438 texObj = get_texobj(ctx, target, GL_FALSE);
439 if (!texObj)
440 return;
441
442 switch (pname) {
443 case GL_TEXTURE_BORDER_COLOR:
444 {
445 /* convert int params to float */
446 GLfloat fparams[4];
447 fparams[0] = INT_TO_FLOAT(params[0]);
448 fparams[1] = INT_TO_FLOAT(params[1]);
449 fparams[2] = INT_TO_FLOAT(params[2]);
450 fparams[3] = INT_TO_FLOAT(params[3]);
451 need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
452 }
453 break;
454 case GL_TEXTURE_MIN_LOD:
455 case GL_TEXTURE_MAX_LOD:
456 case GL_TEXTURE_PRIORITY:
457 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
458 case GL_TEXTURE_LOD_BIAS:
459 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
460 {
461 /* convert int param to float */
462 GLfloat fparams[4];
463 fparams[0] = (GLfloat) params[0];
464 fparams[1] = fparams[2] = fparams[3] = 0.0F;
465 need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
466 }
467 break;
468 default:
469 /* this will generate an error if pname is illegal */
470 need_update = set_tex_parameteri(ctx, texObj, pname, params);
471 }
472
473 if (ctx->Driver.TexParameter && need_update) {
474 GLfloat fparams[4];
475 fparams[0] = INT_TO_FLOAT(params[0]);
476 if (pname == GL_TEXTURE_BORDER_COLOR ||
477 pname == GL_TEXTURE_CROP_RECT_OES) {
478 fparams[1] = INT_TO_FLOAT(params[1]);
479 fparams[2] = INT_TO_FLOAT(params[2]);
480 fparams[3] = INT_TO_FLOAT(params[3]);
481 }
482 ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams);
483 }
484 }
485
486
487 /**
488 * Set tex parameter to integer value(s). Primarily intended to set
489 * integer-valued texture border color (for integer-valued textures).
490 * New in GL 3.0.
491 */
492 void GLAPIENTRY
493 _mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
494 {
495 struct gl_texture_object *texObj;
496 GET_CURRENT_CONTEXT(ctx);
497 ASSERT_OUTSIDE_BEGIN_END(ctx);
498
499 texObj = get_texobj(ctx, target, GL_FALSE);
500 if (!texObj)
501 return;
502
503 switch (pname) {
504 case GL_TEXTURE_BORDER_COLOR:
505 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
506 /* set the integer-valued border color */
507 COPY_4V(texObj->Sampler.BorderColor.i, params);
508 break;
509 default:
510 _mesa_TexParameteriv(target, pname, params);
511 break;
512 }
513 /* XXX no driver hook for TexParameterIiv() yet */
514 }
515
516
517 /**
518 * Set tex parameter to unsigned integer value(s). Primarily intended to set
519 * uint-valued texture border color (for integer-valued textures).
520 * New in GL 3.0
521 */
522 void GLAPIENTRY
523 _mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
524 {
525 struct gl_texture_object *texObj;
526 GET_CURRENT_CONTEXT(ctx);
527 ASSERT_OUTSIDE_BEGIN_END(ctx);
528
529 texObj = get_texobj(ctx, target, GL_FALSE);
530 if (!texObj)
531 return;
532
533 switch (pname) {
534 case GL_TEXTURE_BORDER_COLOR:
535 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
536 /* set the unsigned integer-valued border color */
537 COPY_4V(texObj->Sampler.BorderColor.ui, params);
538 break;
539 default:
540 _mesa_TexParameteriv(target, pname, (const GLint *) params);
541 break;
542 }
543 /* XXX no driver hook for TexParameterIuiv() yet */
544 }
545
546
547 void GLAPIENTRY
548 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
549 GLenum pname, GLfloat *params )
550 {
551 GLint iparam;
552 _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
553 *params = (GLfloat) iparam;
554 }
555
556
557 void GLAPIENTRY
558 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
559 GLenum pname, GLint *params )
560 {
561 struct gl_texture_object *texObj;
562 const struct gl_texture_image *img = NULL;
563 GLint maxLevels;
564 gl_format texFormat;
565 GET_CURRENT_CONTEXT(ctx);
566 ASSERT_OUTSIDE_BEGIN_END(ctx);
567
568 /* this will catch bad target values */
569 maxLevels = _mesa_max_texture_levels(ctx, target);
570 if (maxLevels == 0) {
571 _mesa_error(ctx, GL_INVALID_ENUM,
572 "glGetTexLevelParameter[if]v(target=0x%x)", target);
573 return;
574 }
575
576 if (level < 0 || level >= maxLevels) {
577 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
578 return;
579 }
580
581 texObj = _mesa_select_tex_object(ctx, target);
582
583 img = _mesa_select_tex_image(ctx, texObj, target, level);
584 if (!img || img->TexFormat == MESA_FORMAT_NONE) {
585 /* undefined texture image */
586 if (pname == GL_TEXTURE_COMPONENTS)
587 *params = 1;
588 else
589 *params = 0;
590 return;
591 }
592
593 texFormat = img->TexFormat;
594
595 switch (pname) {
596 case GL_TEXTURE_WIDTH:
597 *params = img->Width;
598 break;
599 case GL_TEXTURE_HEIGHT:
600 *params = img->Height;
601 break;
602 case GL_TEXTURE_DEPTH:
603 *params = img->Depth;
604 break;
605 case GL_TEXTURE_INTERNAL_FORMAT:
606 *params = img->InternalFormat;
607 break;
608 case GL_TEXTURE_BORDER:
609 *params = img->Border;
610 break;
611 case GL_TEXTURE_RED_SIZE:
612 case GL_TEXTURE_GREEN_SIZE:
613 case GL_TEXTURE_BLUE_SIZE:
614 case GL_TEXTURE_ALPHA_SIZE:
615 if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
616 *params = _mesa_get_format_bits(texFormat, pname);
617 else
618 *params = 0;
619 break;
620 case GL_TEXTURE_INTENSITY_SIZE:
621 case GL_TEXTURE_LUMINANCE_SIZE:
622 if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) {
623 *params = _mesa_get_format_bits(texFormat, pname);
624 if (*params == 0) {
625 /* intensity or luminance is probably stored as RGB[A] */
626 *params = MIN2(_mesa_get_format_bits(texFormat,
627 GL_TEXTURE_RED_SIZE),
628 _mesa_get_format_bits(texFormat,
629 GL_TEXTURE_GREEN_SIZE));
630 }
631 }
632 else {
633 *params = 0;
634 }
635 break;
636
637 /* GL_ARB_texture_float */
638 case GL_TEXTURE_RED_TYPE_ARB:
639 case GL_TEXTURE_GREEN_TYPE_ARB:
640 case GL_TEXTURE_BLUE_TYPE_ARB:
641 case GL_TEXTURE_ALPHA_TYPE_ARB:
642 case GL_TEXTURE_LUMINANCE_TYPE_ARB:
643 case GL_TEXTURE_INTENSITY_TYPE_ARB:
644 case GL_TEXTURE_DEPTH_TYPE_ARB:
645 if (!ctx->Extensions.ARB_texture_float)
646 goto invalid_pname;
647 if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
648 *params = _mesa_get_format_datatype(texFormat);
649 else
650 *params = GL_NONE;
651 break;
652
653 default:
654 goto invalid_pname;
655 }
656
657 /* no error if we get here */
658 return;
659
660 invalid_pname:
661 _mesa_error(ctx, GL_INVALID_ENUM,
662 "glGetTexLevelParameter[if]v(pname=%s)",
663 _mesa_lookup_enum_by_nr(pname));
664 }
665
666
667
668 void GLAPIENTRY
669 _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
670 {
671 struct gl_texture_object *obj;
672 GET_CURRENT_CONTEXT(ctx);
673 ASSERT_OUTSIDE_BEGIN_END(ctx);
674
675 obj = get_texobj(ctx, target, GL_TRUE);
676 if (!obj)
677 return;
678
679 _mesa_lock_texture(ctx, obj);
680 switch (pname) {
681 case GL_TEXTURE_MAG_FILTER:
682 *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter);
683 break;
684 case GL_TEXTURE_MIN_FILTER:
685 *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter);
686 break;
687 case GL_TEXTURE_WRAP_S:
688 *params = ENUM_TO_FLOAT(obj->Sampler.WrapS);
689 break;
690 case GL_TEXTURE_WRAP_T:
691 *params = ENUM_TO_FLOAT(obj->Sampler.WrapT);
692 break;
693 case GL_TEXTURE_WRAP_R:
694 *params = ENUM_TO_FLOAT(obj->Sampler.WrapR);
695 break;
696 case GL_TEXTURE_BORDER_COLOR:
697 if (ctx->NewState & _NEW_BUFFERS)
698 _mesa_update_state_locked(ctx);
699 params[0] = obj->Sampler.BorderColor.f[0];
700 params[1] = obj->Sampler.BorderColor.f[1];
701 params[2] = obj->Sampler.BorderColor.f[2];
702 params[3] = obj->Sampler.BorderColor.f[3];
703 break;
704 case GL_TEXTURE_RESIDENT:
705 *params = 1.0F;
706 break;
707 case GL_TEXTURE_PRIORITY:
708 *params = obj->Priority;
709 break;
710 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
711 if (!ctx->Extensions.EXT_texture_filter_anisotropic)
712 goto invalid_pname;
713 *params = obj->Sampler.MaxAnisotropy;
714 break;
715
716 case GL_TEXTURE_IMMUTABLE_FORMAT:
717 if (!ctx->Extensions.ARB_texture_storage)
718 goto invalid_pname;
719 *params = (GLfloat) obj->Immutable;
720 break;
721
722 default:
723 goto invalid_pname;
724 }
725
726 /* no error if we get here */
727 _mesa_unlock_texture(ctx, obj);
728 return;
729
730 invalid_pname:
731 _mesa_unlock_texture(ctx, obj);
732 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", pname);
733 }
734
735
736 void GLAPIENTRY
737 _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
738 {
739 struct gl_texture_object *obj;
740 GET_CURRENT_CONTEXT(ctx);
741 ASSERT_OUTSIDE_BEGIN_END(ctx);
742
743 obj = get_texobj(ctx, target, GL_TRUE);
744 if (!obj)
745 return;
746
747 _mesa_lock_texture(ctx, obj);
748 switch (pname) {
749 case GL_TEXTURE_MAG_FILTER:
750 *params = (GLint) obj->Sampler.MagFilter;
751 break;;
752 case GL_TEXTURE_MIN_FILTER:
753 *params = (GLint) obj->Sampler.MinFilter;
754 break;;
755 case GL_TEXTURE_WRAP_S:
756 *params = (GLint) obj->Sampler.WrapS;
757 break;;
758 case GL_TEXTURE_WRAP_T:
759 *params = (GLint) obj->Sampler.WrapT;
760 break;;
761 case GL_TEXTURE_WRAP_R:
762 *params = (GLint) obj->Sampler.WrapR;
763 break;;
764 case GL_TEXTURE_BORDER_COLOR:
765 {
766 GLfloat b[4];
767 b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
768 b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
769 b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
770 b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
771 params[0] = FLOAT_TO_INT(b[0]);
772 params[1] = FLOAT_TO_INT(b[1]);
773 params[2] = FLOAT_TO_INT(b[2]);
774 params[3] = FLOAT_TO_INT(b[3]);
775 }
776 break;;
777 case GL_TEXTURE_RESIDENT:
778 *params = 1;
779 break;;
780 case GL_TEXTURE_PRIORITY:
781 *params = FLOAT_TO_INT(obj->Priority);
782 break;
783 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
784 if (!ctx->Extensions.EXT_texture_filter_anisotropic)
785 goto invalid_pname;
786 *params = (GLint) obj->Sampler.MaxAnisotropy;
787 break;
788
789 case GL_TEXTURE_IMMUTABLE_FORMAT:
790 if (!ctx->Extensions.ARB_texture_storage)
791 goto invalid_pname;
792 *params = (GLint) obj->Immutable;
793 break;
794
795 default:
796 goto invalid_pname;
797 }
798
799 /* no error if we get here */
800 _mesa_unlock_texture(ctx, obj);
801 return;
802
803 invalid_pname:
804 _mesa_unlock_texture(ctx, obj);
805 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname);
806 }
807
808
809 /** New in GL 3.0 */
810 void GLAPIENTRY
811 _mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
812 {
813 struct gl_texture_object *texObj;
814 GET_CURRENT_CONTEXT(ctx);
815 ASSERT_OUTSIDE_BEGIN_END(ctx);
816
817 texObj = get_texobj(ctx, target, GL_TRUE);
818 if (!texObj)
819 return;
820
821 switch (pname) {
822 case GL_TEXTURE_BORDER_COLOR:
823 COPY_4V(params, texObj->Sampler.BorderColor.i);
824 break;
825 default:
826 _mesa_GetTexParameteriv(target, pname, params);
827 }
828 }
829
830
831 /** New in GL 3.0 */
832 void GLAPIENTRY
833 _mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *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_TRUE);
840 if (!texObj)
841 return;
842
843 switch (pname) {
844 case GL_TEXTURE_BORDER_COLOR:
845 COPY_4V(params, texObj->Sampler.BorderColor.i);
846 break;
847 default:
848 {
849 GLint ip[4];
850 _mesa_GetTexParameteriv(target, pname, ip);
851 params[0] = ip[0];
852 if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT ||
853 pname == GL_TEXTURE_CROP_RECT_OES) {
854 params[1] = ip[1];
855 params[2] = ip[2];
856 params[3] = ip[3];
857 }
858 }
859 }
860 }