mesa: fix typo (s/feadback/feedback/). Fixes broken selection/feedback.
[mesa.git] / src / mesa / main / texparam.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.1
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file texparam.c
27 *
28 * glTexParameter-related functions
29 */
30
31
32 #include "main/glheader.h"
33 #include "main/context.h"
34 #include "main/enums.h"
35 #include "main/colormac.h"
36 #include "main/macros.h"
37 #include "main/texcompress.h"
38 #include "main/texparam.h"
39 #include "main/teximage.h"
40
41
42 /**
43 * Check if a coordinate wrap mode is supported for the texture target.
44 * \return GL_TRUE if legal, GL_FALSE otherwise
45 */
46 static GLboolean
47 validate_texture_wrap_mode(GLcontext * ctx, GLenum target, GLenum wrap)
48 {
49 const struct gl_extensions * const e = & ctx->Extensions;
50
51 if (wrap == GL_CLAMP || wrap == GL_CLAMP_TO_EDGE ||
52 (wrap == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
53 /* any texture target */
54 return GL_TRUE;
55 }
56 else if (target != GL_TEXTURE_RECTANGLE_NV &&
57 (wrap == GL_REPEAT ||
58 (wrap == GL_MIRRORED_REPEAT &&
59 e->ARB_texture_mirrored_repeat) ||
60 (wrap == GL_MIRROR_CLAMP_EXT &&
61 (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
62 (wrap == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
63 (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
64 (wrap == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
65 (e->EXT_texture_mirror_clamp)))) {
66 /* non-rectangle texture */
67 return GL_TRUE;
68 }
69
70 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
71 return GL_FALSE;
72 }
73
74
75 void GLAPIENTRY
76 _mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param )
77 {
78 _mesa_TexParameterfv(target, pname, &param);
79 }
80
81
82 void GLAPIENTRY
83 _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
84 {
85 const GLenum eparam = (GLenum) (GLint) params[0];
86 struct gl_texture_unit *texUnit;
87 struct gl_texture_object *texObj;
88 GET_CURRENT_CONTEXT(ctx);
89 ASSERT_OUTSIDE_BEGIN_END(ctx);
90
91 if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
92 _mesa_debug(ctx, "glTexParameter %s %s %.1f(%s)...\n",
93 _mesa_lookup_enum_by_nr(target),
94 _mesa_lookup_enum_by_nr(pname),
95 *params,
96 _mesa_lookup_enum_by_nr(eparam));
97
98 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
99 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameterfv(current unit)");
100 return;
101 }
102
103 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
104
105 switch (target) {
106 case GL_TEXTURE_1D:
107 texObj = texUnit->Current1D;
108 break;
109 case GL_TEXTURE_2D:
110 texObj = texUnit->Current2D;
111 break;
112 case GL_TEXTURE_3D:
113 texObj = texUnit->Current3D;
114 break;
115 case GL_TEXTURE_CUBE_MAP:
116 if (!ctx->Extensions.ARB_texture_cube_map) {
117 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
118 return;
119 }
120 texObj = texUnit->CurrentCubeMap;
121 break;
122 case GL_TEXTURE_RECTANGLE_NV:
123 if (!ctx->Extensions.NV_texture_rectangle) {
124 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
125 return;
126 }
127 texObj = texUnit->CurrentRect;
128 break;
129 case GL_TEXTURE_1D_ARRAY_EXT:
130 if (!ctx->Extensions.MESA_texture_array) {
131 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
132 return;
133 }
134 texObj = texUnit->Current1DArray;
135 break;
136 case GL_TEXTURE_2D_ARRAY_EXT:
137 if (!ctx->Extensions.MESA_texture_array) {
138 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
139 return;
140 }
141 texObj = texUnit->Current2DArray;
142 break;
143 default:
144 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
145 return;
146 }
147
148 switch (pname) {
149 case GL_TEXTURE_MIN_FILTER:
150 /* A small optimization */
151 if (texObj->MinFilter == eparam)
152 return;
153 if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
154 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
155 texObj->MinFilter = eparam;
156 }
157 else if ((eparam==GL_NEAREST_MIPMAP_NEAREST ||
158 eparam==GL_LINEAR_MIPMAP_NEAREST ||
159 eparam==GL_NEAREST_MIPMAP_LINEAR ||
160 eparam==GL_LINEAR_MIPMAP_LINEAR) &&
161 texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
162 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
163 texObj->MinFilter = eparam;
164 }
165 else {
166 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
167 return;
168 }
169 break;
170 case GL_TEXTURE_MAG_FILTER:
171 /* A small optimization */
172 if (texObj->MagFilter == eparam)
173 return;
174
175 if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
176 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
177 texObj->MagFilter = eparam;
178 }
179 else {
180 _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
181 return;
182 }
183 break;
184 case GL_TEXTURE_WRAP_S:
185 if (texObj->WrapS == eparam)
186 return;
187 if (validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
188 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
189 texObj->WrapS = eparam;
190 }
191 else {
192 return;
193 }
194 break;
195 case GL_TEXTURE_WRAP_T:
196 if (texObj->WrapT == eparam)
197 return;
198 if (validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
199 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
200 texObj->WrapT = eparam;
201 }
202 else {
203 return;
204 }
205 break;
206 case GL_TEXTURE_WRAP_R:
207 if (texObj->WrapR == eparam)
208 return;
209 if (validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
210 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
211 texObj->WrapR = eparam;
212 }
213 else {
214 return;
215 }
216 break;
217 case GL_TEXTURE_BORDER_COLOR:
218 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
219 texObj->BorderColor[RCOMP] = params[0];
220 texObj->BorderColor[GCOMP] = params[1];
221 texObj->BorderColor[BCOMP] = params[2];
222 texObj->BorderColor[ACOMP] = params[3];
223 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[RCOMP], params[0]);
224 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[GCOMP], params[1]);
225 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[BCOMP], params[2]);
226 UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[ACOMP], params[3]);
227 break;
228 case GL_TEXTURE_MIN_LOD:
229 if (texObj->MinLod == params[0])
230 return;
231 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
232 texObj->MinLod = params[0];
233 break;
234 case GL_TEXTURE_MAX_LOD:
235 if (texObj->MaxLod == params[0])
236 return;
237 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
238 texObj->MaxLod = params[0];
239 break;
240 case GL_TEXTURE_BASE_LEVEL:
241 if (params[0] < 0.0) {
242 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)");
243 return;
244 }
245 if (target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0.0) {
246 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)");
247 return;
248 }
249 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
250 texObj->BaseLevel = (GLint) params[0];
251 break;
252 case GL_TEXTURE_MAX_LEVEL:
253 if (params[0] < 0.0) {
254 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)");
255 return;
256 }
257 if (target == GL_TEXTURE_RECTANGLE_ARB) {
258 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(param)");
259 return;
260 }
261 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
262 texObj->MaxLevel = (GLint) params[0];
263 break;
264 case GL_TEXTURE_PRIORITY:
265 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
266 texObj->Priority = CLAMP( params[0], 0.0F, 1.0F );
267 break;
268 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
269 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
270 if (params[0] < 1.0) {
271 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
272 return;
273 }
274 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
275 /* clamp to max, that's what NVIDIA does */
276 texObj->MaxAnisotropy = MIN2(params[0],
277 ctx->Const.MaxTextureMaxAnisotropy);
278 }
279 else {
280 _mesa_error(ctx, GL_INVALID_ENUM,
281 "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
282 return;
283 }
284 break;
285 case GL_TEXTURE_COMPARE_SGIX:
286 if (ctx->Extensions.SGIX_shadow) {
287 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
288 texObj->CompareFlag = params[0] ? GL_TRUE : GL_FALSE;
289 }
290 else {
291 _mesa_error(ctx, GL_INVALID_ENUM,
292 "glTexParameter(pname=GL_TEXTURE_COMPARE_SGIX)");
293 return;
294 }
295 break;
296 case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
297 if (ctx->Extensions.SGIX_shadow) {
298 GLenum op = (GLenum) params[0];
299 if (op == GL_TEXTURE_LEQUAL_R_SGIX ||
300 op == GL_TEXTURE_GEQUAL_R_SGIX) {
301 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
302 texObj->CompareOperator = op;
303 }
304 else {
305 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)");
306 }
307 }
308 else {
309 _mesa_error(ctx, GL_INVALID_ENUM,
310 "glTexParameter(pname=GL_TEXTURE_COMPARE_OPERATOR_SGIX)");
311 return;
312 }
313 break;
314 case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
315 if (ctx->Extensions.SGIX_shadow_ambient) {
316 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
317 texObj->ShadowAmbient = CLAMP(params[0], 0.0F, 1.0F);
318 }
319 else {
320 _mesa_error(ctx, GL_INVALID_ENUM,
321 "glTexParameter(pname=GL_SHADOW_AMBIENT_SGIX)");
322 return;
323 }
324 break;
325 case GL_GENERATE_MIPMAP_SGIS:
326 if (ctx->Extensions.SGIS_generate_mipmap) {
327 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
328 texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
329 }
330 else {
331 _mesa_error(ctx, GL_INVALID_ENUM,
332 "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)");
333 return;
334 }
335 break;
336 case GL_TEXTURE_COMPARE_MODE_ARB:
337 if (ctx->Extensions.ARB_shadow) {
338 const GLenum mode = (GLenum) params[0];
339 if (mode == GL_NONE || mode == GL_COMPARE_R_TO_TEXTURE_ARB) {
340 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
341 texObj->CompareMode = mode;
342 }
343 else {
344 _mesa_error(ctx, GL_INVALID_ENUM,
345 "glTexParameter(bad GL_TEXTURE_COMPARE_MODE_ARB: 0x%x)", mode);
346 return;
347 }
348 }
349 else {
350 _mesa_error(ctx, GL_INVALID_ENUM,
351 "glTexParameter(pname=GL_TEXTURE_COMPARE_MODE_ARB)");
352 return;
353 }
354 break;
355 case GL_TEXTURE_COMPARE_FUNC_ARB:
356 if (ctx->Extensions.ARB_shadow) {
357 const GLenum func = (GLenum) params[0];
358 if (func == GL_LEQUAL || func == GL_GEQUAL) {
359 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
360 texObj->CompareFunc = func;
361 }
362 else if (ctx->Extensions.EXT_shadow_funcs &&
363 (func == GL_EQUAL ||
364 func == GL_NOTEQUAL ||
365 func == GL_LESS ||
366 func == GL_GREATER ||
367 func == GL_ALWAYS ||
368 func == GL_NEVER)) {
369 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
370 texObj->CompareFunc = func;
371 }
372 else {
373 _mesa_error(ctx, GL_INVALID_ENUM,
374 "glTexParameter(bad GL_TEXTURE_COMPARE_FUNC_ARB)");
375 return;
376 }
377 }
378 else {
379 _mesa_error(ctx, GL_INVALID_ENUM,
380 "glTexParameter(pname=GL_TEXTURE_COMPARE_FUNC_ARB)");
381 return;
382 }
383 break;
384 case GL_DEPTH_TEXTURE_MODE_ARB:
385 if (ctx->Extensions.ARB_depth_texture) {
386 const GLenum result = (GLenum) params[0];
387 if (result == GL_LUMINANCE || result == GL_INTENSITY
388 || result == GL_ALPHA) {
389 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
390 texObj->DepthMode = result;
391 }
392 else {
393 _mesa_error(ctx, GL_INVALID_ENUM,
394 "glTexParameter(bad GL_DEPTH_TEXTURE_MODE_ARB)");
395 return;
396 }
397 }
398 else {
399 _mesa_error(ctx, GL_INVALID_ENUM,
400 "glTexParameter(pname=GL_DEPTH_TEXTURE_MODE_ARB)");
401 return;
402 }
403 break;
404 case GL_TEXTURE_LOD_BIAS:
405 /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias*/
406 if (ctx->Extensions.EXT_texture_lod_bias) {
407 if (texObj->LodBias != params[0]) {
408 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
409 texObj->LodBias = params[0];
410 }
411 }
412 break;
413 #ifdef FEATURE_OES_draw_texture
414 case GL_TEXTURE_CROP_RECT_OES:
415 texObj->CropRect[0] = (GLint) params[0];
416 texObj->CropRect[1] = (GLint) params[1];
417 texObj->CropRect[2] = (GLint) params[2];
418 texObj->CropRect[3] = (GLint) params[3];
419 break;
420 #endif
421
422 default:
423 _mesa_error(ctx, GL_INVALID_ENUM,
424 "glTexParameter(pname=0x%x)", pname);
425 return;
426 }
427
428 texObj->_Complete = GL_FALSE;
429
430 if (ctx->Driver.TexParameter) {
431 (*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params );
432 }
433 }
434
435
436 void GLAPIENTRY
437 _mesa_TexParameteri( GLenum target, GLenum pname, GLint param )
438 {
439 GLfloat fparam[4];
440 if (pname == GL_TEXTURE_PRIORITY)
441 fparam[0] = INT_TO_FLOAT(param);
442 else
443 fparam[0] = (GLfloat) param;
444 fparam[1] = fparam[2] = fparam[3] = 0.0;
445 _mesa_TexParameterfv(target, pname, fparam);
446 }
447
448
449 void GLAPIENTRY
450 _mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params )
451 {
452 GLfloat fparam[4];
453 if (pname == GL_TEXTURE_BORDER_COLOR) {
454 fparam[0] = INT_TO_FLOAT(params[0]);
455 fparam[1] = INT_TO_FLOAT(params[1]);
456 fparam[2] = INT_TO_FLOAT(params[2]);
457 fparam[3] = INT_TO_FLOAT(params[3]);
458 }
459 else if (pname == GL_TEXTURE_CROP_RECT_OES) {
460 fparam[0] = (GLfloat) params[0];
461 fparam[1] = (GLfloat) params[1];
462 fparam[2] = (GLfloat) params[2];
463 fparam[3] = (GLfloat) params[3];
464 }
465 else {
466 if (pname == GL_TEXTURE_PRIORITY)
467 fparam[0] = INT_TO_FLOAT(params[0]);
468 else
469 fparam[0] = (GLfloat) params[0];
470 fparam[1] = fparam[2] = fparam[3] = 0.0F;
471 }
472 _mesa_TexParameterfv(target, pname, fparam);
473 }
474
475
476 void GLAPIENTRY
477 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
478 GLenum pname, GLfloat *params )
479 {
480 GLint iparam;
481 _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
482 *params = (GLfloat) iparam;
483 }
484
485
486 static GLuint
487 tex_image_dimensions(GLcontext *ctx, GLenum target)
488 {
489 switch (target) {
490 case GL_TEXTURE_1D:
491 case GL_PROXY_TEXTURE_1D:
492 return 1;
493 case GL_TEXTURE_2D:
494 case GL_PROXY_TEXTURE_2D:
495 return 2;
496 case GL_TEXTURE_3D:
497 case GL_PROXY_TEXTURE_3D:
498 return 3;
499 case GL_TEXTURE_CUBE_MAP:
500 case GL_PROXY_TEXTURE_CUBE_MAP:
501 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
502 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
503 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
504 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
505 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
506 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
507 return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
508 case GL_TEXTURE_RECTANGLE_NV:
509 case GL_PROXY_TEXTURE_RECTANGLE_NV:
510 return ctx->Extensions.NV_texture_rectangle ? 2 : 0;
511 case GL_TEXTURE_1D_ARRAY_EXT:
512 case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
513 return ctx->Extensions.MESA_texture_array ? 2 : 0;
514 case GL_TEXTURE_2D_ARRAY_EXT:
515 case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
516 return ctx->Extensions.MESA_texture_array ? 3 : 0;
517 default:
518 _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
519 return 0;
520 }
521 }
522
523
524 void GLAPIENTRY
525 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
526 GLenum pname, GLint *params )
527 {
528 const struct gl_texture_unit *texUnit;
529 struct gl_texture_object *texObj;
530 const struct gl_texture_image *img = NULL;
531 GLuint dimensions;
532 GLboolean isProxy;
533 GLint maxLevels;
534 GET_CURRENT_CONTEXT(ctx);
535 ASSERT_OUTSIDE_BEGIN_END(ctx);
536
537 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
538 _mesa_error(ctx, GL_INVALID_OPERATION,
539 "glGetTexLevelParameteriv(current unit)");
540 return;
541 }
542
543 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
544
545 /* this will catch bad target values */
546 dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */
547 if (dimensions == 0) {
548 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
549 return;
550 }
551
552 maxLevels = _mesa_max_texture_levels(ctx, target);
553 if (maxLevels == 0) {
554 /* should not happen since <target> was just checked above */
555 _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter");
556 return;
557 }
558
559 if (level < 0 || level >= maxLevels) {
560 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
561 return;
562 }
563
564 texObj = _mesa_select_tex_object(ctx, texUnit, target);
565 _mesa_lock_texture(ctx, texObj);
566
567 img = _mesa_select_tex_image(ctx, texObj, target, level);
568 if (!img || !img->TexFormat) {
569 /* undefined texture image */
570 if (pname == GL_TEXTURE_COMPONENTS)
571 *params = 1;
572 else
573 *params = 0;
574 goto out;
575 }
576
577 isProxy = _mesa_is_proxy_texture(target);
578
579 switch (pname) {
580 case GL_TEXTURE_WIDTH:
581 *params = img->Width;
582 break;
583 case GL_TEXTURE_HEIGHT:
584 *params = img->Height;
585 break;
586 case GL_TEXTURE_DEPTH:
587 *params = img->Depth;
588 break;
589 case GL_TEXTURE_INTERNAL_FORMAT:
590 *params = img->InternalFormat;
591 break;
592 case GL_TEXTURE_BORDER:
593 *params = img->Border;
594 break;
595 case GL_TEXTURE_RED_SIZE:
596 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
597 *params = img->TexFormat->RedBits;
598 else
599 *params = 0;
600 break;
601 case GL_TEXTURE_GREEN_SIZE:
602 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
603 *params = img->TexFormat->GreenBits;
604 else
605 *params = 0;
606 break;
607 case GL_TEXTURE_BLUE_SIZE:
608 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
609 *params = img->TexFormat->BlueBits;
610 else
611 *params = 0;
612 break;
613 case GL_TEXTURE_ALPHA_SIZE:
614 if (img->_BaseFormat == GL_ALPHA ||
615 img->_BaseFormat == GL_LUMINANCE_ALPHA ||
616 img->_BaseFormat == GL_RGBA)
617 *params = img->TexFormat->AlphaBits;
618 else
619 *params = 0;
620 break;
621 case GL_TEXTURE_INTENSITY_SIZE:
622 if (img->_BaseFormat != GL_INTENSITY)
623 *params = 0;
624 else if (img->TexFormat->IntensityBits > 0)
625 *params = img->TexFormat->IntensityBits;
626 else /* intensity probably stored as rgb texture */
627 *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
628 break;
629 case GL_TEXTURE_LUMINANCE_SIZE:
630 if (img->_BaseFormat != GL_LUMINANCE &&
631 img->_BaseFormat != GL_LUMINANCE_ALPHA)
632 *params = 0;
633 else if (img->TexFormat->LuminanceBits > 0)
634 *params = img->TexFormat->LuminanceBits;
635 else /* luminance probably stored as rgb texture */
636 *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
637 break;
638 case GL_TEXTURE_INDEX_SIZE_EXT:
639 if (img->_BaseFormat == GL_COLOR_INDEX)
640 *params = img->TexFormat->IndexBits;
641 else
642 *params = 0;
643 break;
644 case GL_TEXTURE_DEPTH_SIZE_ARB:
645 if (ctx->Extensions.SGIX_depth_texture ||
646 ctx->Extensions.ARB_depth_texture)
647 *params = img->TexFormat->DepthBits;
648 else
649 _mesa_error(ctx, GL_INVALID_ENUM,
650 "glGetTexLevelParameter[if]v(pname)");
651 break;
652 case GL_TEXTURE_STENCIL_SIZE_EXT:
653 if (ctx->Extensions.EXT_packed_depth_stencil) {
654 *params = img->TexFormat->StencilBits;
655 }
656 else {
657 _mesa_error(ctx, GL_INVALID_ENUM,
658 "glGetTexLevelParameter[if]v(pname)");
659 }
660 break;
661
662 /* GL_ARB_texture_compression */
663 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
664 if (ctx->Extensions.ARB_texture_compression) {
665 if (img->IsCompressed && !isProxy) {
666 /* Don't use ctx->Driver.CompressedTextureSize() since that
667 * may returned a padded hardware size.
668 */
669 *params = _mesa_compressed_texture_size(ctx, img->Width,
670 img->Height, img->Depth,
671 img->TexFormat->MesaFormat);
672 }
673 else {
674 _mesa_error(ctx, GL_INVALID_OPERATION,
675 "glGetTexLevelParameter[if]v(pname)");
676 }
677 }
678 else {
679 _mesa_error(ctx, GL_INVALID_ENUM,
680 "glGetTexLevelParameter[if]v(pname)");
681 }
682 break;
683 case GL_TEXTURE_COMPRESSED:
684 if (ctx->Extensions.ARB_texture_compression) {
685 *params = (GLint) img->IsCompressed;
686 }
687 else {
688 _mesa_error(ctx, GL_INVALID_ENUM,
689 "glGetTexLevelParameter[if]v(pname)");
690 }
691 break;
692
693 /* GL_ARB_texture_float */
694 case GL_TEXTURE_RED_TYPE_ARB:
695 if (ctx->Extensions.ARB_texture_float) {
696 *params = img->TexFormat->RedBits ? img->TexFormat->DataType : GL_NONE;
697 }
698 else {
699 _mesa_error(ctx, GL_INVALID_ENUM,
700 "glGetTexLevelParameter[if]v(pname)");
701 }
702 break;
703 case GL_TEXTURE_GREEN_TYPE_ARB:
704 if (ctx->Extensions.ARB_texture_float) {
705 *params = img->TexFormat->GreenBits ? img->TexFormat->DataType : GL_NONE;
706 }
707 else {
708 _mesa_error(ctx, GL_INVALID_ENUM,
709 "glGetTexLevelParameter[if]v(pname)");
710 }
711 break;
712 case GL_TEXTURE_BLUE_TYPE_ARB:
713 if (ctx->Extensions.ARB_texture_float) {
714 *params = img->TexFormat->BlueBits ? img->TexFormat->DataType : GL_NONE;
715 }
716 else {
717 _mesa_error(ctx, GL_INVALID_ENUM,
718 "glGetTexLevelParameter[if]v(pname)");
719 }
720 break;
721 case GL_TEXTURE_ALPHA_TYPE_ARB:
722 if (ctx->Extensions.ARB_texture_float) {
723 *params = img->TexFormat->AlphaBits ? img->TexFormat->DataType : GL_NONE;
724 }
725 else {
726 _mesa_error(ctx, GL_INVALID_ENUM,
727 "glGetTexLevelParameter[if]v(pname)");
728 }
729 break;
730 case GL_TEXTURE_LUMINANCE_TYPE_ARB:
731 if (ctx->Extensions.ARB_texture_float) {
732 *params = img->TexFormat->LuminanceBits ? img->TexFormat->DataType : GL_NONE;
733 }
734 else {
735 _mesa_error(ctx, GL_INVALID_ENUM,
736 "glGetTexLevelParameter[if]v(pname)");
737 }
738 break;
739 case GL_TEXTURE_INTENSITY_TYPE_ARB:
740 if (ctx->Extensions.ARB_texture_float) {
741 *params = img->TexFormat->IntensityBits ? img->TexFormat->DataType : GL_NONE;
742 }
743 else {
744 _mesa_error(ctx, GL_INVALID_ENUM,
745 "glGetTexLevelParameter[if]v(pname)");
746 }
747 break;
748 case GL_TEXTURE_DEPTH_TYPE_ARB:
749 if (ctx->Extensions.ARB_texture_float) {
750 *params = img->TexFormat->DepthBits ? img->TexFormat->DataType : GL_NONE;
751 }
752 else {
753 _mesa_error(ctx, GL_INVALID_ENUM,
754 "glGetTexLevelParameter[if]v(pname)");
755 }
756 break;
757
758 default:
759 _mesa_error(ctx, GL_INVALID_ENUM,
760 "glGetTexLevelParameter[if]v(pname)");
761 }
762
763 out:
764 _mesa_unlock_texture(ctx, texObj);
765 }
766
767
768
769 void GLAPIENTRY
770 _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
771 {
772 struct gl_texture_unit *texUnit;
773 struct gl_texture_object *obj;
774 GLboolean error = GL_FALSE;
775 GET_CURRENT_CONTEXT(ctx);
776 ASSERT_OUTSIDE_BEGIN_END(ctx);
777
778 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
779 _mesa_error(ctx, GL_INVALID_OPERATION,
780 "glGetTexParameterfv(current unit)");
781 return;
782 }
783
784 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
785
786 obj = _mesa_select_tex_object(ctx, texUnit, target);
787 if (!obj) {
788 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
789 return;
790 }
791
792 _mesa_lock_texture(ctx, obj);
793 switch (pname) {
794 case GL_TEXTURE_MAG_FILTER:
795 *params = ENUM_TO_FLOAT(obj->MagFilter);
796 break;
797 case GL_TEXTURE_MIN_FILTER:
798 *params = ENUM_TO_FLOAT(obj->MinFilter);
799 break;
800 case GL_TEXTURE_WRAP_S:
801 *params = ENUM_TO_FLOAT(obj->WrapS);
802 break;
803 case GL_TEXTURE_WRAP_T:
804 *params = ENUM_TO_FLOAT(obj->WrapT);
805 break;
806 case GL_TEXTURE_WRAP_R:
807 *params = ENUM_TO_FLOAT(obj->WrapR);
808 break;
809 case GL_TEXTURE_BORDER_COLOR:
810 params[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
811 params[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
812 params[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
813 params[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
814 break;
815 case GL_TEXTURE_RESIDENT:
816 {
817 GLboolean resident;
818 if (ctx->Driver.IsTextureResident)
819 resident = ctx->Driver.IsTextureResident(ctx, obj);
820 else
821 resident = GL_TRUE;
822 *params = ENUM_TO_FLOAT(resident);
823 }
824 break;
825 case GL_TEXTURE_PRIORITY:
826 *params = obj->Priority;
827 break;
828 case GL_TEXTURE_MIN_LOD:
829 *params = obj->MinLod;
830 break;
831 case GL_TEXTURE_MAX_LOD:
832 *params = obj->MaxLod;
833 break;
834 case GL_TEXTURE_BASE_LEVEL:
835 *params = (GLfloat) obj->BaseLevel;
836 break;
837 case GL_TEXTURE_MAX_LEVEL:
838 *params = (GLfloat) obj->MaxLevel;
839 break;
840 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
841 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
842 *params = obj->MaxAnisotropy;
843 }
844 else
845 error = 1;
846 break;
847 case GL_TEXTURE_COMPARE_SGIX:
848 if (ctx->Extensions.SGIX_shadow) {
849 *params = (GLfloat) obj->CompareFlag;
850 }
851 else
852 error = 1;
853 break;
854 case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
855 if (ctx->Extensions.SGIX_shadow) {
856 *params = (GLfloat) obj->CompareOperator;
857 }
858 else
859 error = 1;
860 break;
861 case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
862 if (ctx->Extensions.SGIX_shadow_ambient) {
863 *params = obj->ShadowAmbient;
864 }
865 else
866 error = 1;
867 break;
868 case GL_GENERATE_MIPMAP_SGIS:
869 if (ctx->Extensions.SGIS_generate_mipmap) {
870 *params = (GLfloat) obj->GenerateMipmap;
871 }
872 else
873 error = 1;
874 break;
875 case GL_TEXTURE_COMPARE_MODE_ARB:
876 if (ctx->Extensions.ARB_shadow) {
877 *params = (GLfloat) obj->CompareMode;
878 }
879 else
880 error = 1;
881 break;
882 case GL_TEXTURE_COMPARE_FUNC_ARB:
883 if (ctx->Extensions.ARB_shadow) {
884 *params = (GLfloat) obj->CompareFunc;
885 }
886 else
887 error = 1;
888 break;
889 case GL_DEPTH_TEXTURE_MODE_ARB:
890 if (ctx->Extensions.ARB_depth_texture) {
891 *params = (GLfloat) obj->DepthMode;
892 }
893 else
894 error = 1;
895 break;
896 case GL_TEXTURE_LOD_BIAS:
897 if (ctx->Extensions.EXT_texture_lod_bias) {
898 *params = obj->LodBias;
899 }
900 else
901 error = 1;
902 break;
903 #ifdef FEATURE_OES_draw_texture
904 case GL_TEXTURE_CROP_RECT_OES:
905 params[0] = obj->CropRect[0];
906 params[0] = obj->CropRect[1];
907 params[0] = obj->CropRect[2];
908 params[0] = obj->CropRect[3];
909 break;
910 #endif
911 default:
912 error = 1;
913 break;
914 }
915 if (error)
916 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)",
917 pname);
918
919 _mesa_unlock_texture(ctx, obj);
920 }
921
922
923 void GLAPIENTRY
924 _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
925 {
926 struct gl_texture_unit *texUnit;
927 struct gl_texture_object *obj;
928 GET_CURRENT_CONTEXT(ctx);
929 ASSERT_OUTSIDE_BEGIN_END(ctx);
930
931 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
932 _mesa_error(ctx, GL_INVALID_OPERATION,
933 "glGetTexParameteriv(current unit)");
934 return;
935 }
936
937 texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
938
939 obj = _mesa_select_tex_object(ctx, texUnit, target);
940 if (!obj) {
941 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)");
942 return;
943 }
944
945 switch (pname) {
946 case GL_TEXTURE_MAG_FILTER:
947 *params = (GLint) obj->MagFilter;
948 return;
949 case GL_TEXTURE_MIN_FILTER:
950 *params = (GLint) obj->MinFilter;
951 return;
952 case GL_TEXTURE_WRAP_S:
953 *params = (GLint) obj->WrapS;
954 return;
955 case GL_TEXTURE_WRAP_T:
956 *params = (GLint) obj->WrapT;
957 return;
958 case GL_TEXTURE_WRAP_R:
959 *params = (GLint) obj->WrapR;
960 return;
961 case GL_TEXTURE_BORDER_COLOR:
962 {
963 GLfloat b[4];
964 b[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
965 b[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
966 b[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
967 b[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
968 params[0] = FLOAT_TO_INT(b[0]);
969 params[1] = FLOAT_TO_INT(b[1]);
970 params[2] = FLOAT_TO_INT(b[2]);
971 params[3] = FLOAT_TO_INT(b[3]);
972 }
973 return;
974 case GL_TEXTURE_RESIDENT:
975 {
976 GLboolean resident;
977 if (ctx->Driver.IsTextureResident)
978 resident = ctx->Driver.IsTextureResident(ctx, obj);
979 else
980 resident = GL_TRUE;
981 *params = (GLint) resident;
982 }
983 return;
984 case GL_TEXTURE_PRIORITY:
985 *params = FLOAT_TO_INT(obj->Priority);
986 return;
987 case GL_TEXTURE_MIN_LOD:
988 *params = (GLint) obj->MinLod;
989 return;
990 case GL_TEXTURE_MAX_LOD:
991 *params = (GLint) obj->MaxLod;
992 return;
993 case GL_TEXTURE_BASE_LEVEL:
994 *params = obj->BaseLevel;
995 return;
996 case GL_TEXTURE_MAX_LEVEL:
997 *params = obj->MaxLevel;
998 return;
999 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1000 if (ctx->Extensions.EXT_texture_filter_anisotropic) {
1001 *params = (GLint) obj->MaxAnisotropy;
1002 return;
1003 }
1004 break;
1005 case GL_TEXTURE_COMPARE_SGIX:
1006 if (ctx->Extensions.SGIX_shadow) {
1007 *params = (GLint) obj->CompareFlag;
1008 return;
1009 }
1010 break;
1011 case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
1012 if (ctx->Extensions.SGIX_shadow) {
1013 *params = (GLint) obj->CompareOperator;
1014 return;
1015 }
1016 break;
1017 case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
1018 if (ctx->Extensions.SGIX_shadow_ambient) {
1019 *params = (GLint) FLOAT_TO_INT(obj->ShadowAmbient);
1020 return;
1021 }
1022 break;
1023 case GL_GENERATE_MIPMAP_SGIS:
1024 if (ctx->Extensions.SGIS_generate_mipmap) {
1025 *params = (GLint) obj->GenerateMipmap;
1026 return;
1027 }
1028 break;
1029 case GL_TEXTURE_COMPARE_MODE_ARB:
1030 if (ctx->Extensions.ARB_shadow) {
1031 *params = (GLint) obj->CompareMode;
1032 return;
1033 }
1034 break;
1035 case GL_TEXTURE_COMPARE_FUNC_ARB:
1036 if (ctx->Extensions.ARB_shadow) {
1037 *params = (GLint) obj->CompareFunc;
1038 return;
1039 }
1040 break;
1041 case GL_DEPTH_TEXTURE_MODE_ARB:
1042 if (ctx->Extensions.ARB_depth_texture) {
1043 *params = (GLint) obj->DepthMode;
1044 return;
1045 }
1046 break;
1047 case GL_TEXTURE_LOD_BIAS:
1048 if (ctx->Extensions.EXT_texture_lod_bias) {
1049 *params = (GLint) obj->LodBias;
1050 return;
1051 }
1052 break;
1053 #ifdef FEATURE_OES_draw_texture
1054 case GL_TEXTURE_CROP_RECT_OES:
1055 params[0] = obj->CropRect[0];
1056 params[0] = obj->CropRect[1];
1057 params[0] = obj->CropRect[2];
1058 params[0] = obj->CropRect[3];
1059 break;
1060 #endif
1061 default:
1062 ; /* silence warnings */
1063 }
1064 /* If we get here, pname was an unrecognized enum */
1065 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname);
1066 }