Subversion Repositories Kolibri OS

Rev

Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 1
/*
2
 * Mesa 3-D graphics library
3
 *
4
 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5
 * Copyright (C) 2009  VMware, Inc.  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
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
 * OTHER DEALINGS IN THE SOFTWARE.
24
 */
25
 
26
/**
27
 * \file texparam.c
28
 *
29
 * glTexParameter-related functions
30
 */
31
 
32
#include 
33
#include "main/glheader.h"
34
#include "main/blend.h"
35
#include "main/colormac.h"
36
#include "main/context.h"
37
#include "main/enums.h"
38
#include "main/formats.h"
39
#include "main/glformats.h"
40
#include "main/macros.h"
41
#include "main/mtypes.h"
42
#include "main/state.h"
43
#include "main/texcompress.h"
44
#include "main/texobj.h"
45
#include "main/texparam.h"
46
#include "main/teximage.h"
47
#include "main/texstate.h"
48
#include "program/prog_instruction.h"
49
 
50
 
51
/**
52
 * Check if a coordinate wrap mode is supported for the texture target.
53
 * \return GL_TRUE if legal, GL_FALSE otherwise
54
 */
55
static GLboolean
56
validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap)
57
{
58
   const struct gl_extensions * const e = & ctx->Extensions;
59
   const bool is_desktop_gl = _mesa_is_desktop_gl(ctx);
60
   bool supported;
61
 
62
   switch (wrap) {
63
   case GL_CLAMP:
64
      /* GL_CLAMP was removed in the core profile, and it has never existed in
65
       * OpenGL ES.
66
       */
67
      supported = (ctx->API == API_OPENGL_COMPAT)
68
         && (target != GL_TEXTURE_EXTERNAL_OES);
69
      break;
70
 
71
   case GL_CLAMP_TO_EDGE:
72
      supported = true;
73
      break;
74
 
75
   case GL_CLAMP_TO_BORDER:
76
      supported = is_desktop_gl && e->ARB_texture_border_clamp
77
         && (target != GL_TEXTURE_EXTERNAL_OES);
78
      break;
79
 
80
   case GL_REPEAT:
81
   case GL_MIRRORED_REPEAT:
82
      supported = (target != GL_TEXTURE_RECTANGLE_NV)
83
         && (target != GL_TEXTURE_EXTERNAL_OES);
84
      break;
85
 
86
   case GL_MIRROR_CLAMP_EXT:
87
   case GL_MIRROR_CLAMP_TO_EDGE_EXT:
88
      supported = is_desktop_gl
89
         && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)
90
	 && (target != GL_TEXTURE_RECTANGLE_NV)
91
         && (target != GL_TEXTURE_EXTERNAL_OES);
92
      break;
93
 
94
   case GL_MIRROR_CLAMP_TO_BORDER_EXT:
95
      supported = is_desktop_gl && e->EXT_texture_mirror_clamp
96
	 && (target != GL_TEXTURE_RECTANGLE_NV)
97
         && (target != GL_TEXTURE_EXTERNAL_OES);
98
      break;
99
 
100
   default:
101
      supported = false;
102
      break;
103
   }
104
 
105
   if (!supported)
106
      _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap );
107
 
108
   return supported;
109
}
110
 
111
 
112
/**
113
 * Get current texture object for given target.
114
 * Return NULL if any error (and record the error).
115
 * Note that this is different from _mesa_select_tex_object() in that proxy
116
 * targets are not accepted.
117
 * Only the glGetTexLevelParameter() functions accept proxy targets.
118
 */
119
static struct gl_texture_object *
120
get_texobj(struct gl_context *ctx, GLenum target, GLboolean get)
121
{
122
   struct gl_texture_unit *texUnit;
123
 
124
   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
125
      _mesa_error(ctx, GL_INVALID_OPERATION,
126
                  "gl%sTexParameter(current unit)", get ? "Get" : "");
127
      return NULL;
128
   }
129
 
130
   texUnit = _mesa_get_current_tex_unit(ctx);
131
 
132
   switch (target) {
133
   case GL_TEXTURE_1D:
134
      if (_mesa_is_desktop_gl(ctx))
135
         return texUnit->CurrentTex[TEXTURE_1D_INDEX];
136
      break;
137
   case GL_TEXTURE_2D:
138
      return texUnit->CurrentTex[TEXTURE_2D_INDEX];
139
   case GL_TEXTURE_3D:
140
      if (ctx->API != API_OPENGLES)
141
         return texUnit->CurrentTex[TEXTURE_3D_INDEX];
142
      break;
143
   case GL_TEXTURE_CUBE_MAP:
144
      if (ctx->Extensions.ARB_texture_cube_map) {
145
         return texUnit->CurrentTex[TEXTURE_CUBE_INDEX];
146
      }
147
      break;
148
   case GL_TEXTURE_RECTANGLE_NV:
149
      if (_mesa_is_desktop_gl(ctx)
150
          && ctx->Extensions.NV_texture_rectangle) {
151
         return texUnit->CurrentTex[TEXTURE_RECT_INDEX];
152
      }
153
      break;
154
   case GL_TEXTURE_1D_ARRAY_EXT:
155
      if (_mesa_is_desktop_gl(ctx)
156
          && (ctx->Extensions.MESA_texture_array ||
157
              ctx->Extensions.EXT_texture_array)) {
158
         return texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX];
159
      }
160
      break;
161
   case GL_TEXTURE_2D_ARRAY_EXT:
162
      if ((_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx))
163
          && (ctx->Extensions.MESA_texture_array ||
164
              ctx->Extensions.EXT_texture_array)) {
165
         return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX];
166
      }
167
      break;
168
   case GL_TEXTURE_EXTERNAL_OES:
169
      if (_mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external) {
170
         return texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX];
171
      }
172
      break;
173
   case GL_TEXTURE_CUBE_MAP_ARRAY:
174
      if (ctx->Extensions.ARB_texture_cube_map_array) {
175
         return texUnit->CurrentTex[TEXTURE_CUBE_ARRAY_INDEX];
176
      }
177
      break;
178
   case GL_TEXTURE_2D_MULTISAMPLE:
179
      if (ctx->Extensions.ARB_texture_multisample) {
180
         return texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_INDEX];
181
      }
182
      break;
183
   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
184
      if (ctx->Extensions.ARB_texture_multisample) {
185
         return texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX];
186
      }
187
      break;
188
   default:
189
      ;
190
   }
191
 
192
   _mesa_error(ctx, GL_INVALID_ENUM,
193
                  "gl%sTexParameter(target)", get ? "Get" : "");
194
   return NULL;
195
}
196
 
197
 
198
/**
199
 * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE.
200
 * \return -1 if error.
201
 */
202
static GLint
203
comp_to_swizzle(GLenum comp)
204
{
205
   switch (comp) {
206
   case GL_RED:
207
      return SWIZZLE_X;
208
   case GL_GREEN:
209
      return SWIZZLE_Y;
210
   case GL_BLUE:
211
      return SWIZZLE_Z;
212
   case GL_ALPHA:
213
      return SWIZZLE_W;
214
   case GL_ZERO:
215
      return SWIZZLE_ZERO;
216
   case GL_ONE:
217
      return SWIZZLE_ONE;
218
   default:
219
      return -1;
220
   }
221
}
222
 
223
 
224
static void
225
set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz)
226
{
227
   ASSERT(comp < 4);
228
   ASSERT(swz <= SWIZZLE_NIL);
229
   {
230
      GLuint mask = 0x7 << (3 * comp);
231
      GLuint s = (*swizzle & ~mask) | (swz << (3 * comp));
232
      *swizzle = s;
233
   }
234
}
235
 
236
 
237
/**
238
 * This is called just prior to changing any texture object state which
239
 * will not effect texture completeness.
240
 */
241
static inline void
242
flush(struct gl_context *ctx)
243
{
244
   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
245
}
246
 
247
 
248
/**
249
 * This is called just prior to changing any texture object state which
250
 * can effect texture completeness (texture base level, max level).
251
 * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE
252
 * state flag and then mark the texture object as 'incomplete' so that any
253
 * per-texture derived state gets recomputed.
254
 */
255
static inline void
256
incomplete(struct gl_context *ctx, struct gl_texture_object *texObj)
257
{
258
   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
259
   _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
260
}
261
 
262
 
263
static GLboolean
264
target_allows_setting_sampler_parameters(GLenum target)
265
{
266
   switch (target) {
267
   case GL_TEXTURE_2D_MULTISAMPLE:
268
   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
269
      return GL_FALSE;
270
 
271
   default:
272
      return GL_TRUE;
273
   }
274
}
275
 
276
 
277
/**
278
 * Set an integer-valued texture parameter
279
 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
280
 */
281
static GLboolean
282
set_tex_parameteri(struct gl_context *ctx,
283
                   struct gl_texture_object *texObj,
284
                   GLenum pname, const GLint *params)
285
{
286
   switch (pname) {
287
   case GL_TEXTURE_MIN_FILTER:
288
      if (!target_allows_setting_sampler_parameters(texObj->Target))
289
         goto invalid_operation;
290
 
291
      if (texObj->Sampler.MinFilter == params[0])
292
         return GL_FALSE;
293
      switch (params[0]) {
294
      case GL_NEAREST:
295
      case GL_LINEAR:
296
         flush(ctx);
297
         texObj->Sampler.MinFilter = params[0];
298
         return GL_TRUE;
299
      case GL_NEAREST_MIPMAP_NEAREST:
300
      case GL_LINEAR_MIPMAP_NEAREST:
301
      case GL_NEAREST_MIPMAP_LINEAR:
302
      case GL_LINEAR_MIPMAP_LINEAR:
303
         if (texObj->Target != GL_TEXTURE_RECTANGLE_NV &&
304
             texObj->Target != GL_TEXTURE_EXTERNAL_OES) {
305
            flush(ctx);
306
            texObj->Sampler.MinFilter = params[0];
307
            return GL_TRUE;
308
         }
309
         /* fall-through */
310
      default:
311
         goto invalid_param;
312
      }
313
      return GL_FALSE;
314
 
315
   case GL_TEXTURE_MAG_FILTER:
316
      if (!target_allows_setting_sampler_parameters(texObj->Target))
317
         goto invalid_operation;
318
 
319
      if (texObj->Sampler.MagFilter == params[0])
320
         return GL_FALSE;
321
      switch (params[0]) {
322
      case GL_NEAREST:
323
      case GL_LINEAR:
324
         flush(ctx); /* does not effect completeness */
325
         texObj->Sampler.MagFilter = params[0];
326
         return GL_TRUE;
327
      default:
328
         goto invalid_param;
329
      }
330
      return GL_FALSE;
331
 
332
   case GL_TEXTURE_WRAP_S:
333
      if (!target_allows_setting_sampler_parameters(texObj->Target))
334
         goto invalid_operation;
335
 
336
      if (texObj->Sampler.WrapS == params[0])
337
         return GL_FALSE;
338
      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
339
         flush(ctx);
340
         texObj->Sampler.WrapS = params[0];
341
         return GL_TRUE;
342
      }
343
      return GL_FALSE;
344
 
345
   case GL_TEXTURE_WRAP_T:
346
      if (!target_allows_setting_sampler_parameters(texObj->Target))
347
         goto invalid_operation;
348
 
349
      if (texObj->Sampler.WrapT == params[0])
350
         return GL_FALSE;
351
      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
352
         flush(ctx);
353
         texObj->Sampler.WrapT = params[0];
354
         return GL_TRUE;
355
      }
356
      return GL_FALSE;
357
 
358
   case GL_TEXTURE_WRAP_R:
359
      if (!target_allows_setting_sampler_parameters(texObj->Target))
360
         goto invalid_operation;
361
 
362
      if (texObj->Sampler.WrapR == params[0])
363
         return GL_FALSE;
364
      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
365
         flush(ctx);
366
         texObj->Sampler.WrapR = params[0];
367
         return GL_TRUE;
368
      }
369
      return GL_FALSE;
370
 
371
   case GL_TEXTURE_BASE_LEVEL:
372
      if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
373
         goto invalid_pname;
374
 
375
      if (texObj->BaseLevel == params[0])
376
         return GL_FALSE;
377
 
378
      if ((texObj->Target == GL_TEXTURE_2D_MULTISAMPLE ||
379
           texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && params[0] != 0)
380
         goto invalid_operation;
381
 
382
      if (params[0] < 0 ||
383
          (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) {
384
         _mesa_error(ctx, GL_INVALID_VALUE,
385
                     "glTexParameter(param=%d)", params[0]);
386
         return GL_FALSE;
387
      }
388
      incomplete(ctx, texObj);
389
      texObj->BaseLevel = params[0];
390
      return GL_TRUE;
391
 
392
   case GL_TEXTURE_MAX_LEVEL:
393
      if (texObj->MaxLevel == params[0])
394
         return GL_FALSE;
395
 
396
      if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) {
397
         _mesa_error(ctx, GL_INVALID_VALUE,
398
                     "glTexParameter(param=%d)", params[0]);
399
         return GL_FALSE;
400
      }
401
      incomplete(ctx, texObj);
402
      texObj->MaxLevel = params[0];
403
      return GL_TRUE;
404
 
405
   case GL_GENERATE_MIPMAP_SGIS:
406
      if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
407
         goto invalid_pname;
408
 
409
      if (params[0] && texObj->Target == GL_TEXTURE_EXTERNAL_OES)
410
         goto invalid_param;
411
      if (texObj->GenerateMipmap != params[0]) {
412
         /* no flush() */
413
	 texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
414
	 return GL_TRUE;
415
      }
416
      return GL_FALSE;
417
 
418
   case GL_TEXTURE_COMPARE_MODE_ARB:
419
      if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
420
          || _mesa_is_gles3(ctx)) {
421
 
422
         if (!target_allows_setting_sampler_parameters(texObj->Target))
423
            goto invalid_operation;
424
 
425
         if (texObj->Sampler.CompareMode == params[0])
426
            return GL_FALSE;
427
         if (params[0] == GL_NONE ||
428
             params[0] == GL_COMPARE_R_TO_TEXTURE_ARB) {
429
            flush(ctx);
430
            texObj->Sampler.CompareMode = params[0];
431
            return GL_TRUE;
432
         }
433
         goto invalid_param;
434
      }
435
      goto invalid_pname;
436
 
437
   case GL_TEXTURE_COMPARE_FUNC_ARB:
438
      if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
439
          || _mesa_is_gles3(ctx)) {
440
 
441
         if (!target_allows_setting_sampler_parameters(texObj->Target))
442
            goto invalid_operation;
443
 
444
         if (texObj->Sampler.CompareFunc == params[0])
445
            return GL_FALSE;
446
         switch (params[0]) {
447
         case GL_LEQUAL:
448
         case GL_GEQUAL:
449
         case GL_EQUAL:
450
         case GL_NOTEQUAL:
451
         case GL_LESS:
452
         case GL_GREATER:
453
         case GL_ALWAYS:
454
         case GL_NEVER:
455
            flush(ctx);
456
            texObj->Sampler.CompareFunc = params[0];
457
            return GL_TRUE;
458
         default:
459
            goto invalid_param;
460
         }
461
      }
462
      goto invalid_pname;
463
 
464
   case GL_DEPTH_TEXTURE_MODE_ARB:
465
      /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has never
466
       * existed in OpenGL ES.
467
       */
468
      if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_depth_texture) {
469
         if (texObj->DepthMode == params[0])
470
            return GL_FALSE;
471
         if (params[0] == GL_LUMINANCE ||
472
             params[0] == GL_INTENSITY ||
473
             params[0] == GL_ALPHA ||
474
             (ctx->Extensions.ARB_texture_rg && params[0] == GL_RED)) {
475
            flush(ctx);
476
            texObj->DepthMode = params[0];
477
            return GL_TRUE;
478
         }
479
         goto invalid_param;
480
      }
481
      goto invalid_pname;
482
 
483
   case GL_TEXTURE_CROP_RECT_OES:
484
      if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
485
         goto invalid_pname;
486
 
487
      texObj->CropRect[0] = params[0];
488
      texObj->CropRect[1] = params[1];
489
      texObj->CropRect[2] = params[2];
490
      texObj->CropRect[3] = params[3];
491
      return GL_TRUE;
492
 
493
   case GL_TEXTURE_SWIZZLE_R_EXT:
494
   case GL_TEXTURE_SWIZZLE_G_EXT:
495
   case GL_TEXTURE_SWIZZLE_B_EXT:
496
   case GL_TEXTURE_SWIZZLE_A_EXT:
497
      if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle)
498
          || _mesa_is_gles3(ctx)) {
499
         const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
500
         const GLint swz = comp_to_swizzle(params[0]);
501
         if (swz < 0) {
502
            _mesa_error(ctx, GL_INVALID_OPERATION,
503
                        "glTexParameter(swizzle 0x%x)", params[0]);
504
            return GL_FALSE;
505
         }
506
         ASSERT(comp < 4);
507
 
508
         flush(ctx);
509
         texObj->Swizzle[comp] = params[0];
510
         set_swizzle_component(&texObj->_Swizzle, comp, swz);
511
         return GL_TRUE;
512
      }
513
      goto invalid_pname;
514
 
515
   case GL_TEXTURE_SWIZZLE_RGBA_EXT:
516
      if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle)
517
          || _mesa_is_gles3(ctx)) {
518
         GLuint comp;
519
         flush(ctx);
520
         for (comp = 0; comp < 4; comp++) {
521
            const GLint swz = comp_to_swizzle(params[comp]);
522
            if (swz >= 0) {
523
               texObj->Swizzle[comp] = params[comp];
524
               set_swizzle_component(&texObj->_Swizzle, comp, swz);
525
            }
526
            else {
527
               _mesa_error(ctx, GL_INVALID_OPERATION,
528
                           "glTexParameter(swizzle 0x%x)", params[comp]);
529
               return GL_FALSE;
530
            }
531
         }
532
         return GL_TRUE;
533
      }
534
      goto invalid_pname;
535
 
536
   case GL_TEXTURE_SRGB_DECODE_EXT:
537
      if (_mesa_is_desktop_gl(ctx)
538
          && ctx->Extensions.EXT_texture_sRGB_decode) {
539
         GLenum decode = params[0];
540
 
541
         if (!target_allows_setting_sampler_parameters(texObj->Target))
542
            goto invalid_operation;
543
 
544
	 if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) {
545
	    if (texObj->Sampler.sRGBDecode != decode) {
546
	       flush(ctx);
547
	       texObj->Sampler.sRGBDecode = decode;
548
	    }
549
	    return GL_TRUE;
550
	 }
551
      }
552
      goto invalid_pname;
553
 
554
   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
555
      if (_mesa_is_desktop_gl(ctx)
556
          && ctx->Extensions.AMD_seamless_cubemap_per_texture) {
557
         GLenum param = params[0];
558
 
559
         if (!target_allows_setting_sampler_parameters(texObj->Target))
560
            goto invalid_operation;
561
 
562
         if (param != GL_TRUE && param != GL_FALSE) {
563
            goto invalid_param;
564
         }
565
         if (param != texObj->Sampler.CubeMapSeamless) {
566
            flush(ctx);
567
            texObj->Sampler.CubeMapSeamless = param;
568
         }
569
         return GL_TRUE;
570
      }
571
      goto invalid_pname;
572
 
573
   default:
574
      goto invalid_pname;
575
   }
576
 
577
invalid_pname:
578
   _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)",
579
               _mesa_lookup_enum_by_nr(pname));
580
   return GL_FALSE;
581
 
582
invalid_param:
583
   _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param=%s)",
584
               _mesa_lookup_enum_by_nr(params[0]));
585
   return GL_FALSE;
586
 
587
invalid_operation:
588
   _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)",
589
               _mesa_lookup_enum_by_nr(pname));
590
   return GL_FALSE;
591
}
592
 
593
 
594
/**
595
 * Set a float-valued texture parameter
596
 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
597
 */
598
static GLboolean
599
set_tex_parameterf(struct gl_context *ctx,
600
                   struct gl_texture_object *texObj,
601
                   GLenum pname, const GLfloat *params)
602
{
603
   switch (pname) {
604
   case GL_TEXTURE_MIN_LOD:
605
      if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
606
         goto invalid_pname;
607
 
608
      if (!target_allows_setting_sampler_parameters(texObj->Target))
609
         goto invalid_operation;
610
 
611
      if (texObj->Sampler.MinLod == params[0])
612
         return GL_FALSE;
613
      flush(ctx);
614
      texObj->Sampler.MinLod = params[0];
615
      return GL_TRUE;
616
 
617
   case GL_TEXTURE_MAX_LOD:
618
      if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
619
         goto invalid_pname;
620
 
621
      if (!target_allows_setting_sampler_parameters(texObj->Target))
622
         goto invalid_operation;
623
 
624
      if (texObj->Sampler.MaxLod == params[0])
625
         return GL_FALSE;
626
      flush(ctx);
627
      texObj->Sampler.MaxLod = params[0];
628
      return GL_TRUE;
629
 
630
   case GL_TEXTURE_PRIORITY:
631
      if (ctx->API != API_OPENGL_COMPAT)
632
         goto invalid_pname;
633
 
634
      flush(ctx);
635
      texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
636
      return GL_TRUE;
637
 
638
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
639
      if (ctx->Extensions.EXT_texture_filter_anisotropic) {
640
         if (!target_allows_setting_sampler_parameters(texObj->Target))
641
            goto invalid_operation;
642
 
643
         if (texObj->Sampler.MaxAnisotropy == params[0])
644
            return GL_FALSE;
645
         if (params[0] < 1.0) {
646
            _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
647
            return GL_FALSE;
648
         }
649
         flush(ctx);
650
         /* clamp to max, that's what NVIDIA does */
651
         texObj->Sampler.MaxAnisotropy = MIN2(params[0],
652
                                      ctx->Const.MaxTextureMaxAnisotropy);
653
         return GL_TRUE;
654
      }
655
      else {
656
         static GLuint count = 0;
657
         if (count++ < 10)
658
            goto invalid_pname;
659
      }
660
      return GL_FALSE;
661
 
662
   case GL_TEXTURE_LOD_BIAS:
4401 Serge 663
      /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias. */
664
      if (_mesa_is_gles(ctx))
4358 Serge 665
         goto invalid_pname;
666
 
667
      if (!target_allows_setting_sampler_parameters(texObj->Target))
668
         goto invalid_operation;
669
 
670
      if (texObj->Sampler.LodBias != params[0]) {
671
	 flush(ctx);
672
	 texObj->Sampler.LodBias = params[0];
673
	 return GL_TRUE;
674
      }
675
      break;
676
 
677
   case GL_TEXTURE_BORDER_COLOR:
678
      if (!_mesa_is_desktop_gl(ctx))
679
         goto invalid_pname;
680
 
681
      if (!target_allows_setting_sampler_parameters(texObj->Target))
682
         goto invalid_operation;
683
 
684
      flush(ctx);
685
      /* ARB_texture_float disables clamping */
686
      if (ctx->Extensions.ARB_texture_float) {
687
         texObj->Sampler.BorderColor.f[RCOMP] = params[0];
688
         texObj->Sampler.BorderColor.f[GCOMP] = params[1];
689
         texObj->Sampler.BorderColor.f[BCOMP] = params[2];
690
         texObj->Sampler.BorderColor.f[ACOMP] = params[3];
691
      } else {
692
         texObj->Sampler.BorderColor.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F);
693
         texObj->Sampler.BorderColor.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F);
694
         texObj->Sampler.BorderColor.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F);
695
         texObj->Sampler.BorderColor.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F);
696
      }
697
      return GL_TRUE;
698
 
699
   default:
700
      goto invalid_pname;
701
   }
702
   return GL_FALSE;
703
 
704
invalid_pname:
705
   _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)",
706
               _mesa_lookup_enum_by_nr(pname));
707
   return GL_FALSE;
708
 
709
invalid_operation:
710
   _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)",
711
               _mesa_lookup_enum_by_nr(pname));
712
   return GL_FALSE;
713
}
714
 
715
 
716
void GLAPIENTRY
717
_mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
718
{
719
   GLboolean need_update;
720
   struct gl_texture_object *texObj;
721
   GET_CURRENT_CONTEXT(ctx);
722
 
723
   texObj = get_texobj(ctx, target, GL_FALSE);
724
   if (!texObj)
725
      return;
726
 
727
   switch (pname) {
728
   case GL_TEXTURE_MIN_FILTER:
729
   case GL_TEXTURE_MAG_FILTER:
730
   case GL_TEXTURE_WRAP_S:
731
   case GL_TEXTURE_WRAP_T:
732
   case GL_TEXTURE_WRAP_R:
733
   case GL_TEXTURE_BASE_LEVEL:
734
   case GL_TEXTURE_MAX_LEVEL:
735
   case GL_GENERATE_MIPMAP_SGIS:
736
   case GL_TEXTURE_COMPARE_MODE_ARB:
737
   case GL_TEXTURE_COMPARE_FUNC_ARB:
738
   case GL_DEPTH_TEXTURE_MODE_ARB:
739
   case GL_TEXTURE_SRGB_DECODE_EXT:
740
   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
741
   case GL_TEXTURE_SWIZZLE_R_EXT:
742
   case GL_TEXTURE_SWIZZLE_G_EXT:
743
   case GL_TEXTURE_SWIZZLE_B_EXT:
744
   case GL_TEXTURE_SWIZZLE_A_EXT:
745
      {
746
         GLint p[4];
747
         p[0] = (param > 0) ?
748
                ((param > INT_MAX) ? INT_MAX : (GLint) (param + 0.5)) :
749
                ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5));
750
 
751
         p[1] = p[2] = p[3] = 0;
752
         need_update = set_tex_parameteri(ctx, texObj, pname, p);
753
      }
754
      break;
755
   default:
756
      {
757
         /* this will generate an error if pname is illegal */
758
         GLfloat p[4];
759
         p[0] = param;
760
         p[1] = p[2] = p[3] = 0.0F;
761
         need_update = set_tex_parameterf(ctx, texObj, pname, p);
762
      }
763
   }
764
 
765
   if (ctx->Driver.TexParameter && need_update) {
766
      ctx->Driver.TexParameter(ctx, target, texObj, pname, ¶m);
767
   }
768
}
769
 
770
 
771
void GLAPIENTRY
772
_mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
773
{
774
   GLboolean need_update;
775
   struct gl_texture_object *texObj;
776
   GET_CURRENT_CONTEXT(ctx);
777
 
778
   texObj = get_texobj(ctx, target, GL_FALSE);
779
   if (!texObj)
780
      return;
781
 
782
   switch (pname) {
783
   case GL_TEXTURE_MIN_FILTER:
784
   case GL_TEXTURE_MAG_FILTER:
785
   case GL_TEXTURE_WRAP_S:
786
   case GL_TEXTURE_WRAP_T:
787
   case GL_TEXTURE_WRAP_R:
788
   case GL_TEXTURE_BASE_LEVEL:
789
   case GL_TEXTURE_MAX_LEVEL:
790
   case GL_GENERATE_MIPMAP_SGIS:
791
   case GL_TEXTURE_COMPARE_MODE_ARB:
792
   case GL_TEXTURE_COMPARE_FUNC_ARB:
793
   case GL_DEPTH_TEXTURE_MODE_ARB:
794
   case GL_TEXTURE_SRGB_DECODE_EXT:
795
   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
796
      {
797
         /* convert float param to int */
798
         GLint p[4];
799
         p[0] = (GLint) params[0];
800
         p[1] = p[2] = p[3] = 0;
801
         need_update = set_tex_parameteri(ctx, texObj, pname, p);
802
      }
803
      break;
804
   case GL_TEXTURE_CROP_RECT_OES:
805
      {
806
         /* convert float params to int */
807
         GLint iparams[4];
808
         iparams[0] = (GLint) params[0];
809
         iparams[1] = (GLint) params[1];
810
         iparams[2] = (GLint) params[2];
811
         iparams[3] = (GLint) params[3];
812
         need_update = set_tex_parameteri(ctx, texObj, pname, iparams);
813
      }
814
      break;
815
   case GL_TEXTURE_SWIZZLE_R_EXT:
816
   case GL_TEXTURE_SWIZZLE_G_EXT:
817
   case GL_TEXTURE_SWIZZLE_B_EXT:
818
   case GL_TEXTURE_SWIZZLE_A_EXT:
819
   case GL_TEXTURE_SWIZZLE_RGBA_EXT:
820
      {
821
         GLint p[4] = {0, 0, 0, 0};
822
         p[0] = (GLint) params[0];
823
         if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT) {
824
            p[1] = (GLint) params[1];
825
            p[2] = (GLint) params[2];
826
            p[3] = (GLint) params[3];
827
         }
828
         need_update = set_tex_parameteri(ctx, texObj, pname, p);
829
      }
830
      break;
831
   default:
832
      /* this will generate an error if pname is illegal */
833
      need_update = set_tex_parameterf(ctx, texObj, pname, params);
834
   }
835
 
836
   if (ctx->Driver.TexParameter && need_update) {
837
      ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
838
   }
839
}
840
 
841
 
842
void GLAPIENTRY
843
_mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
844
{
845
   GLboolean need_update;
846
   struct gl_texture_object *texObj;
847
   GET_CURRENT_CONTEXT(ctx);
848
 
849
   texObj = get_texobj(ctx, target, GL_FALSE);
850
   if (!texObj)
851
      return;
852
 
853
   switch (pname) {
854
   case GL_TEXTURE_MIN_LOD:
855
   case GL_TEXTURE_MAX_LOD:
856
   case GL_TEXTURE_PRIORITY:
857
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
858
   case GL_TEXTURE_LOD_BIAS:
859
   case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
860
      {
861
         GLfloat fparam[4];
862
         fparam[0] = (GLfloat) param;
863
         fparam[1] = fparam[2] = fparam[3] = 0.0F;
864
         /* convert int param to float */
865
         need_update = set_tex_parameterf(ctx, texObj, pname, fparam);
866
      }
867
      break;
868
   default:
869
      /* this will generate an error if pname is illegal */
870
      {
871
         GLint iparam[4];
872
         iparam[0] = param;
873
         iparam[1] = iparam[2] = iparam[3] = 0;
874
         need_update = set_tex_parameteri(ctx, texObj, pname, iparam);
875
      }
876
   }
877
 
878
   if (ctx->Driver.TexParameter && need_update) {
879
      GLfloat fparam = (GLfloat) param;
880
      ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam);
881
   }
882
}
883
 
884
 
885
void GLAPIENTRY
886
_mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
887
{
888
   GLboolean need_update;
889
   struct gl_texture_object *texObj;
890
   GET_CURRENT_CONTEXT(ctx);
891
 
892
   texObj = get_texobj(ctx, target, GL_FALSE);
893
   if (!texObj)
894
      return;
895
 
896
   switch (pname) {
897
   case GL_TEXTURE_BORDER_COLOR:
898
      {
899
         /* convert int params to float */
900
         GLfloat fparams[4];
901
         fparams[0] = INT_TO_FLOAT(params[0]);
902
         fparams[1] = INT_TO_FLOAT(params[1]);
903
         fparams[2] = INT_TO_FLOAT(params[2]);
904
         fparams[3] = INT_TO_FLOAT(params[3]);
905
         need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
906
      }
907
      break;
908
   case GL_TEXTURE_MIN_LOD:
909
   case GL_TEXTURE_MAX_LOD:
910
   case GL_TEXTURE_PRIORITY:
911
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
912
   case GL_TEXTURE_LOD_BIAS:
913
   case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
914
      {
915
         /* convert int param to float */
916
         GLfloat fparams[4];
917
         fparams[0] = (GLfloat) params[0];
918
         fparams[1] = fparams[2] = fparams[3] = 0.0F;
919
         need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
920
      }
921
      break;
922
   default:
923
      /* this will generate an error if pname is illegal */
924
      need_update = set_tex_parameteri(ctx, texObj, pname, params);
925
   }
926
 
927
   if (ctx->Driver.TexParameter && need_update) {
928
      GLfloat fparams[4];
929
      fparams[0] = INT_TO_FLOAT(params[0]);
930
      if (pname == GL_TEXTURE_BORDER_COLOR ||
931
          pname == GL_TEXTURE_CROP_RECT_OES) {
932
         fparams[1] = INT_TO_FLOAT(params[1]);
933
         fparams[2] = INT_TO_FLOAT(params[2]);
934
         fparams[3] = INT_TO_FLOAT(params[3]);
935
      }
936
      ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams);
937
   }
938
}
939
 
940
 
941
/**
942
 * Set tex parameter to integer value(s).  Primarily intended to set
943
 * integer-valued texture border color (for integer-valued textures).
944
 * New in GL 3.0.
945
 */
946
void GLAPIENTRY
947
_mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
948
{
949
   struct gl_texture_object *texObj;
950
   GET_CURRENT_CONTEXT(ctx);
951
 
952
   texObj = get_texobj(ctx, target, GL_FALSE);
953
   if (!texObj)
954
      return;
955
 
956
   switch (pname) {
957
   case GL_TEXTURE_BORDER_COLOR:
958
      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
959
      /* set the integer-valued border color */
960
      COPY_4V(texObj->Sampler.BorderColor.i, params);
961
      break;
962
   default:
963
      _mesa_TexParameteriv(target, pname, params);
964
      break;
965
   }
966
   /* XXX no driver hook for TexParameterIiv() yet */
967
}
968
 
969
 
970
/**
971
 * Set tex parameter to unsigned integer value(s).  Primarily intended to set
972
 * uint-valued texture border color (for integer-valued textures).
973
 * New in GL 3.0
974
 */
975
void GLAPIENTRY
976
_mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
977
{
978
   struct gl_texture_object *texObj;
979
   GET_CURRENT_CONTEXT(ctx);
980
 
981
   texObj = get_texobj(ctx, target, GL_FALSE);
982
   if (!texObj)
983
      return;
984
 
985
   switch (pname) {
986
   case GL_TEXTURE_BORDER_COLOR:
987
      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
988
      /* set the unsigned integer-valued border color */
989
      COPY_4V(texObj->Sampler.BorderColor.ui, params);
990
      break;
991
   default:
992
      _mesa_TexParameteriv(target, pname, (const GLint *) params);
993
      break;
994
   }
995
   /* XXX no driver hook for TexParameterIuiv() yet */
996
}
997
 
998
 
999
static GLboolean
1000
legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target)
1001
{
1002
   switch (target) {
1003
   case GL_TEXTURE_1D:
1004
   case GL_PROXY_TEXTURE_1D:
1005
   case GL_TEXTURE_2D:
1006
   case GL_PROXY_TEXTURE_2D:
1007
   case GL_TEXTURE_3D:
1008
   case GL_PROXY_TEXTURE_3D:
1009
      return GL_TRUE;
1010
   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
1011
   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
1012
   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
1013
   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
1014
   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
1015
   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
1016
   case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
1017
      return ctx->Extensions.ARB_texture_cube_map;
1018
   case GL_TEXTURE_RECTANGLE_NV:
1019
   case GL_PROXY_TEXTURE_RECTANGLE_NV:
1020
      return ctx->Extensions.NV_texture_rectangle;
1021
   case GL_TEXTURE_1D_ARRAY_EXT:
1022
   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1023
   case GL_TEXTURE_2D_ARRAY_EXT:
1024
   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1025
      return (ctx->Extensions.MESA_texture_array ||
1026
              ctx->Extensions.EXT_texture_array);
1027
   case GL_TEXTURE_BUFFER:
1028
      /* GetTexLevelParameter accepts GL_TEXTURE_BUFFER in GL 3.1+ contexts,
1029
       * but not in earlier versions that expose ARB_texture_buffer_object.
1030
       *
1031
       * From the ARB_texture_buffer_object spec:
1032
       * "(7) Do buffer textures support texture parameters (TexParameter) or
1033
       *      queries (GetTexParameter, GetTexLevelParameter, GetTexImage)?
1034
       *
1035
       *    RESOLVED:  No. [...] Note that the spec edits above don't add
1036
       *    explicit error language for any of these cases.  That is because
1037
       *    each of the functions enumerate the set of valid 
1038
       *    parameters.  Not editing the spec to allow TEXTURE_BUFFER_ARB in
1039
       *    these cases means that target is not legal, and an INVALID_ENUM
1040
       *    error should be generated."
1041
       *
1042
       * From the OpenGL 3.1 spec:
1043
       * "target may also be TEXTURE_BUFFER, indicating the texture buffer."
1044
       */
1045
      return ctx->API == API_OPENGL_CORE && ctx->Version >= 31;
1046
   case GL_TEXTURE_2D_MULTISAMPLE:
1047
   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1048
   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
1049
   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
1050
      return ctx->Extensions.ARB_texture_multisample;
1051
   default:
1052
      return GL_FALSE;
1053
   }
1054
}
1055
 
1056
 
1057
static void
1058
get_tex_level_parameter_image(struct gl_context *ctx,
1059
                              const struct gl_texture_object *texObj,
1060
                              GLenum target, GLint level,
1061
                              GLenum pname, GLint *params)
1062
{
1063
   const struct gl_texture_image *img = NULL;
1064
   gl_format texFormat;
1065
 
1066
   img = _mesa_select_tex_image(ctx, texObj, target, level);
1067
   if (!img || img->TexFormat == MESA_FORMAT_NONE) {
1068
      /* undefined texture image */
1069
      if (pname == GL_TEXTURE_COMPONENTS)
1070
         *params = 1;
1071
      else
1072
         *params = 0;
1073
      return;
1074
   }
1075
 
1076
   texFormat = img->TexFormat;
1077
 
1078
   switch (pname) {
1079
      case GL_TEXTURE_WIDTH:
1080
         *params = img->Width;
1081
         break;
1082
      case GL_TEXTURE_HEIGHT:
1083
         *params = img->Height;
1084
         break;
1085
      case GL_TEXTURE_DEPTH:
1086
         *params = img->Depth;
1087
         break;
1088
      case GL_TEXTURE_INTERNAL_FORMAT:
1089
         if (_mesa_is_format_compressed(texFormat)) {
1090
            /* need to return the actual compressed format */
1091
            *params = _mesa_compressed_format_to_glenum(ctx, texFormat);
1092
         }
1093
         else {
1094
	    /* If the true internal format is not compressed but the user
1095
	     * requested a generic compressed format, we have to return the
1096
	     * generic base format that matches.
1097
	     *
1098
	     * From page 119 (page 129 of the PDF) of the OpenGL 1.3 spec:
1099
	     *
1100
	     *     "If no specific compressed format is available,
1101
	     *     internalformat is instead replaced by the corresponding base
1102
	     *     internal format."
1103
	     *
1104
	     * Otherwise just return the user's requested internal format
1105
	     */
1106
	    const GLenum f =
1107
	       _mesa_gl_compressed_format_base_format(img->InternalFormat);
1108
 
1109
	    *params = (f != 0) ? f : img->InternalFormat;
1110
	 }
1111
         break;
1112
      case GL_TEXTURE_BORDER:
1113
         *params = img->Border;
1114
         break;
1115
      case GL_TEXTURE_RED_SIZE:
1116
      case GL_TEXTURE_GREEN_SIZE:
1117
      case GL_TEXTURE_BLUE_SIZE:
1118
      case GL_TEXTURE_ALPHA_SIZE:
1119
         if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
1120
            *params = _mesa_get_format_bits(texFormat, pname);
1121
         else
1122
            *params = 0;
1123
         break;
1124
      case GL_TEXTURE_INTENSITY_SIZE:
1125
      case GL_TEXTURE_LUMINANCE_SIZE:
1126
         if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) {
1127
            *params = _mesa_get_format_bits(texFormat, pname);
1128
            if (*params == 0) {
1129
               /* intensity or luminance is probably stored as RGB[A] */
1130
               *params = MIN2(_mesa_get_format_bits(texFormat,
1131
                                                    GL_TEXTURE_RED_SIZE),
1132
                              _mesa_get_format_bits(texFormat,
1133
                                                    GL_TEXTURE_GREEN_SIZE));
1134
            }
1135
         }
1136
         else {
1137
            *params = 0;
1138
         }
1139
         break;
1140
      case GL_TEXTURE_DEPTH_SIZE_ARB:
1141
         if (!ctx->Extensions.ARB_depth_texture)
1142
            goto invalid_pname;
1143
         *params = _mesa_get_format_bits(texFormat, pname);
1144
         break;
1145
      case GL_TEXTURE_STENCIL_SIZE_EXT:
1146
         if (!ctx->Extensions.EXT_packed_depth_stencil &&
1147
             !ctx->Extensions.ARB_framebuffer_object)
1148
            goto invalid_pname;
1149
         *params = _mesa_get_format_bits(texFormat, pname);
1150
         break;
1151
      case GL_TEXTURE_SHARED_SIZE:
1152
         if (ctx->Version < 30 &&
1153
             !ctx->Extensions.EXT_texture_shared_exponent)
1154
            goto invalid_pname;
1155
         *params = texFormat == MESA_FORMAT_RGB9_E5_FLOAT ? 5 : 0;
1156
         break;
1157
 
1158
      /* GL_ARB_texture_compression */
1159
      case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
1160
	 if (_mesa_is_format_compressed(texFormat) &&
1161
             !_mesa_is_proxy_texture(target)) {
1162
            *params = _mesa_format_image_size(texFormat, img->Width,
1163
                                              img->Height, img->Depth);
1164
	 }
1165
	 else {
1166
	    _mesa_error(ctx, GL_INVALID_OPERATION,
1167
			"glGetTexLevelParameter[if]v(pname)");
1168
	 }
1169
         break;
1170
      case GL_TEXTURE_COMPRESSED:
1171
         *params = (GLint) _mesa_is_format_compressed(texFormat);
1172
         break;
1173
 
1174
      /* GL_ARB_texture_float */
1175
      case GL_TEXTURE_RED_TYPE_ARB:
1176
      case GL_TEXTURE_GREEN_TYPE_ARB:
1177
      case GL_TEXTURE_BLUE_TYPE_ARB:
1178
      case GL_TEXTURE_ALPHA_TYPE_ARB:
1179
      case GL_TEXTURE_LUMINANCE_TYPE_ARB:
1180
      case GL_TEXTURE_INTENSITY_TYPE_ARB:
1181
      case GL_TEXTURE_DEPTH_TYPE_ARB:
1182
         if (!ctx->Extensions.ARB_texture_float)
1183
            goto invalid_pname;
1184
	 if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
1185
	    *params = _mesa_get_format_datatype(texFormat);
1186
	 else
1187
	    *params = GL_NONE;
1188
         break;
1189
 
1190
      /* GL_ARB_texture_multisample */
1191
      case GL_TEXTURE_SAMPLES:
1192
         if (!ctx->Extensions.ARB_texture_multisample)
1193
            goto invalid_pname;
1194
         *params = img->NumSamples;
1195
         break;
1196
 
1197
      case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
1198
         if (!ctx->Extensions.ARB_texture_multisample)
1199
            goto invalid_pname;
1200
         *params = img->FixedSampleLocations;
1201
         break;
1202
 
1203
      default:
1204
         goto invalid_pname;
1205
   }
1206
 
1207
   /* no error if we get here */
1208
   return;
1209
 
1210
invalid_pname:
1211
   _mesa_error(ctx, GL_INVALID_ENUM,
1212
               "glGetTexLevelParameter[if]v(pname=%s)",
1213
               _mesa_lookup_enum_by_nr(pname));
1214
}
1215
 
1216
 
1217
static void
1218
get_tex_level_parameter_buffer(struct gl_context *ctx,
1219
                               const struct gl_texture_object *texObj,
1220
                               GLenum pname, GLint *params)
1221
{
1222
   const struct gl_buffer_object *bo = texObj->BufferObject;
1223
   gl_format texFormat = texObj->_BufferObjectFormat;
1224
   GLenum internalFormat = texObj->BufferObjectFormat;
1225
   GLenum baseFormat = _mesa_get_format_base_format(texFormat);
1226
 
1227
   if (!bo) {
1228
      /* undefined texture buffer object */
1229
      *params = pname == GL_TEXTURE_COMPONENTS ? 1 : 0;
1230
      return;
1231
   }
1232
 
1233
   switch (pname) {
1234
      case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
1235
         *params = bo->Name;
1236
         break;
1237
      case GL_TEXTURE_WIDTH:
1238
         *params = bo->Size;
1239
         break;
1240
      case GL_TEXTURE_HEIGHT:
1241
      case GL_TEXTURE_DEPTH:
1242
      case GL_TEXTURE_BORDER:
1243
      case GL_TEXTURE_SHARED_SIZE:
1244
      case GL_TEXTURE_COMPRESSED:
1245
         *params = 0;
1246
         break;
1247
      case GL_TEXTURE_INTERNAL_FORMAT:
1248
         *params = internalFormat;
1249
         break;
1250
      case GL_TEXTURE_RED_SIZE:
1251
      case GL_TEXTURE_GREEN_SIZE:
1252
      case GL_TEXTURE_BLUE_SIZE:
1253
      case GL_TEXTURE_ALPHA_SIZE:
1254
         if (_mesa_base_format_has_channel(baseFormat, pname))
1255
            *params = _mesa_get_format_bits(texFormat, pname);
1256
         else
1257
            *params = 0;
1258
         break;
1259
      case GL_TEXTURE_INTENSITY_SIZE:
1260
      case GL_TEXTURE_LUMINANCE_SIZE:
1261
         if (_mesa_base_format_has_channel(baseFormat, pname)) {
1262
            *params = _mesa_get_format_bits(texFormat, pname);
1263
            if (*params == 0) {
1264
               /* intensity or luminance is probably stored as RGB[A] */
1265
               *params = MIN2(_mesa_get_format_bits(texFormat,
1266
                                                    GL_TEXTURE_RED_SIZE),
1267
                              _mesa_get_format_bits(texFormat,
1268
                                                    GL_TEXTURE_GREEN_SIZE));
1269
            }
1270
         } else {
1271
            *params = 0;
1272
         }
1273
         break;
1274
      case GL_TEXTURE_DEPTH_SIZE_ARB:
1275
      case GL_TEXTURE_STENCIL_SIZE_EXT:
1276
         *params = _mesa_get_format_bits(texFormat, pname);
1277
         break;
1278
 
1279
      /* GL_ARB_texture_buffer_range */
1280
      case GL_TEXTURE_BUFFER_OFFSET:
1281
         if (!ctx->Extensions.ARB_texture_buffer_range)
1282
            goto invalid_pname;
1283
         *params = texObj->BufferOffset;
1284
         break;
1285
      case GL_TEXTURE_BUFFER_SIZE:
1286
         if (!ctx->Extensions.ARB_texture_buffer_range)
1287
            goto invalid_pname;
1288
         *params = (texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize;
1289
         break;
1290
 
1291
      /* GL_ARB_texture_compression */
1292
      case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
1293
         /* Always illegal for GL_TEXTURE_BUFFER */
1294
         _mesa_error(ctx, GL_INVALID_OPERATION,
1295
                     "glGetTexLevelParameter[if]v(pname)");
1296
         break;
1297
 
1298
      /* GL_ARB_texture_float */
1299
      case GL_TEXTURE_RED_TYPE_ARB:
1300
      case GL_TEXTURE_GREEN_TYPE_ARB:
1301
      case GL_TEXTURE_BLUE_TYPE_ARB:
1302
      case GL_TEXTURE_ALPHA_TYPE_ARB:
1303
      case GL_TEXTURE_LUMINANCE_TYPE_ARB:
1304
      case GL_TEXTURE_INTENSITY_TYPE_ARB:
1305
      case GL_TEXTURE_DEPTH_TYPE_ARB:
1306
         if (!ctx->Extensions.ARB_texture_float)
1307
            goto invalid_pname;
1308
         if (_mesa_base_format_has_channel(baseFormat, pname))
1309
            *params = _mesa_get_format_datatype(texFormat);
1310
         else
1311
            *params = GL_NONE;
1312
         break;
1313
 
1314
      default:
1315
         goto invalid_pname;
1316
   }
1317
 
1318
   /* no error if we get here */
1319
   return;
1320
 
1321
invalid_pname:
1322
   _mesa_error(ctx, GL_INVALID_ENUM,
1323
               "glGetTexLevelParameter[if]v(pname=%s)",
1324
               _mesa_lookup_enum_by_nr(pname));
1325
}
1326
 
1327
 
1328
void GLAPIENTRY
1329
_mesa_GetTexLevelParameterfv( GLenum target, GLint level,
1330
                              GLenum pname, GLfloat *params )
1331
{
1332
   GLint iparam;
1333
   _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
1334
   *params = (GLfloat) iparam;
1335
}
1336
 
1337
 
1338
void GLAPIENTRY
1339
_mesa_GetTexLevelParameteriv( GLenum target, GLint level,
1340
                              GLenum pname, GLint *params )
1341
{
1342
   const struct gl_texture_unit *texUnit;
1343
   struct gl_texture_object *texObj;
1344
   GLint maxLevels;
1345
   GET_CURRENT_CONTEXT(ctx);
1346
 
1347
   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
1348
      _mesa_error(ctx, GL_INVALID_OPERATION,
1349
                  "glGetTexLevelParameteriv(current unit)");
1350
      return;
1351
   }
1352
 
1353
   texUnit = _mesa_get_current_tex_unit(ctx);
1354
 
1355
   if (!legal_get_tex_level_parameter_target(ctx, target)) {
1356
      _mesa_error(ctx, GL_INVALID_ENUM,
1357
                  "glGetTexLevelParameter[if]v(target=0x%x)", target);
1358
      return;
1359
   }
1360
 
1361
   maxLevels = _mesa_max_texture_levels(ctx, target);
1362
   assert(maxLevels != 0);
1363
 
1364
   if (level < 0 || level >= maxLevels) {
1365
      _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
1366
      return;
1367
   }
1368
 
1369
   texObj = _mesa_select_tex_object(ctx, texUnit, target);
1370
 
1371
   if (target == GL_TEXTURE_BUFFER)
1372
      get_tex_level_parameter_buffer(ctx, texObj, pname, params);
1373
   else
1374
      get_tex_level_parameter_image(ctx, texObj, target, level, pname, params);
1375
}
1376
 
1377
 
1378
void GLAPIENTRY
1379
_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
1380
{
1381
   struct gl_texture_object *obj;
1382
   GET_CURRENT_CONTEXT(ctx);
1383
 
1384
   obj = get_texobj(ctx, target, GL_TRUE);
1385
   if (!obj)
1386
      return;
1387
 
1388
   _mesa_lock_texture(ctx, obj);
1389
   switch (pname) {
1390
      case GL_TEXTURE_MAG_FILTER:
1391
	 *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter);
1392
	 break;
1393
      case GL_TEXTURE_MIN_FILTER:
1394
         *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter);
1395
         break;
1396
      case GL_TEXTURE_WRAP_S:
1397
         *params = ENUM_TO_FLOAT(obj->Sampler.WrapS);
1398
         break;
1399
      case GL_TEXTURE_WRAP_T:
1400
         *params = ENUM_TO_FLOAT(obj->Sampler.WrapT);
1401
         break;
1402
      case GL_TEXTURE_WRAP_R:
1403
         *params = ENUM_TO_FLOAT(obj->Sampler.WrapR);
1404
         break;
1405
      case GL_TEXTURE_BORDER_COLOR:
1406
         if (!_mesa_is_desktop_gl(ctx))
1407
            goto invalid_pname;
1408
 
1409
         if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
1410
            _mesa_update_state_locked(ctx);
1411
         if (_mesa_get_clamp_fragment_color(ctx)) {
1412
            params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
1413
            params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
1414
            params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
1415
            params[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
1416
         }
1417
         else {
1418
            params[0] = obj->Sampler.BorderColor.f[0];
1419
            params[1] = obj->Sampler.BorderColor.f[1];
1420
            params[2] = obj->Sampler.BorderColor.f[2];
1421
            params[3] = obj->Sampler.BorderColor.f[3];
1422
         }
1423
         break;
1424
      case GL_TEXTURE_RESIDENT:
1425
         if (ctx->API != API_OPENGL_COMPAT)
1426
            goto invalid_pname;
1427
 
1428
         *params = 1.0F;
1429
         break;
1430
      case GL_TEXTURE_PRIORITY:
1431
         if (ctx->API != API_OPENGL_COMPAT)
1432
            goto invalid_pname;
1433
 
1434
         *params = obj->Priority;
1435
         break;
1436
      case GL_TEXTURE_MIN_LOD:
1437
         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1438
            goto invalid_pname;
1439
 
1440
         *params = obj->Sampler.MinLod;
1441
         break;
1442
      case GL_TEXTURE_MAX_LOD:
1443
         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1444
            goto invalid_pname;
1445
 
1446
         *params = obj->Sampler.MaxLod;
1447
         break;
1448
      case GL_TEXTURE_BASE_LEVEL:
1449
         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1450
            goto invalid_pname;
1451
 
1452
         *params = (GLfloat) obj->BaseLevel;
1453
         break;
1454
      case GL_TEXTURE_MAX_LEVEL:
1455
         *params = (GLfloat) obj->MaxLevel;
1456
         break;
1457
      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1458
         if (!ctx->Extensions.EXT_texture_filter_anisotropic)
1459
            goto invalid_pname;
1460
         *params = obj->Sampler.MaxAnisotropy;
1461
         break;
1462
      case GL_GENERATE_MIPMAP_SGIS:
1463
         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1464
            goto invalid_pname;
1465
 
1466
	 *params = (GLfloat) obj->GenerateMipmap;
1467
         break;
1468
      case GL_TEXTURE_COMPARE_MODE_ARB:
1469
         if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1470
             && !_mesa_is_gles3(ctx))
1471
            goto invalid_pname;
1472
         *params = (GLfloat) obj->Sampler.CompareMode;
1473
         break;
1474
      case GL_TEXTURE_COMPARE_FUNC_ARB:
1475
         if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1476
             && !_mesa_is_gles3(ctx))
1477
            goto invalid_pname;
1478
         *params = (GLfloat) obj->Sampler.CompareFunc;
1479
         break;
1480
      case GL_DEPTH_TEXTURE_MODE_ARB:
1481
         /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has
1482
          * never existed in OpenGL ES.
1483
          */
1484
         if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
1485
            goto invalid_pname;
1486
         *params = (GLfloat) obj->DepthMode;
1487
         break;
1488
      case GL_TEXTURE_LOD_BIAS:
4401 Serge 1489
         if (_mesa_is_gles(ctx))
4358 Serge 1490
            goto invalid_pname;
1491
 
1492
         *params = obj->Sampler.LodBias;
1493
         break;
1494
      case GL_TEXTURE_CROP_RECT_OES:
1495
         if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
1496
            goto invalid_pname;
1497
 
1498
         params[0] = (GLfloat) obj->CropRect[0];
1499
         params[1] = (GLfloat) obj->CropRect[1];
1500
         params[2] = (GLfloat) obj->CropRect[2];
1501
         params[3] = (GLfloat) obj->CropRect[3];
1502
         break;
1503
 
1504
      case GL_TEXTURE_SWIZZLE_R_EXT:
1505
      case GL_TEXTURE_SWIZZLE_G_EXT:
1506
      case GL_TEXTURE_SWIZZLE_B_EXT:
1507
      case GL_TEXTURE_SWIZZLE_A_EXT:
1508
         if ((!_mesa_is_desktop_gl(ctx)
1509
              || !ctx->Extensions.EXT_texture_swizzle)
1510
             && !_mesa_is_gles3(ctx))
1511
            goto invalid_pname;
1512
         *params = (GLfloat) obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
1513
         break;
1514
 
1515
      case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1516
         if ((!_mesa_is_desktop_gl(ctx)
1517
              || !ctx->Extensions.EXT_texture_swizzle)
1518
             && !_mesa_is_gles3(ctx)) {
1519
            goto invalid_pname;
1520
         }
1521
         else {
1522
            GLuint comp;
1523
            for (comp = 0; comp < 4; comp++) {
1524
               params[comp] = (GLfloat) obj->Swizzle[comp];
1525
            }
1526
         }
1527
         break;
1528
 
1529
      case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1530
         if (!_mesa_is_desktop_gl(ctx)
1531
             || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
1532
            goto invalid_pname;
1533
         *params = (GLfloat) obj->Sampler.CubeMapSeamless;
1534
         break;
1535
 
1536
      case GL_TEXTURE_IMMUTABLE_FORMAT:
1537
         *params = (GLfloat) obj->Immutable;
1538
         break;
1539
 
1540
      case GL_TEXTURE_IMMUTABLE_LEVELS:
1541
         if (!_mesa_is_gles3(ctx))
1542
            goto invalid_pname;
1543
         *params = (GLfloat) obj->ImmutableLevels;
1544
         break;
1545
 
1546
      case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
1547
         if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
1548
            goto invalid_pname;
1549
         *params = (GLfloat) obj->RequiredTextureImageUnits;
1550
         break;
1551
 
1552
      case GL_TEXTURE_SRGB_DECODE_EXT:
1553
         if (!ctx->Extensions.EXT_texture_sRGB_decode)
1554
            goto invalid_pname;
1555
         *params = (GLfloat) obj->Sampler.sRGBDecode;
1556
         break;
1557
 
1558
      default:
1559
         goto invalid_pname;
1560
   }
1561
 
1562
   /* no error if we get here */
1563
   _mesa_unlock_texture(ctx, obj);
1564
   return;
1565
 
1566
invalid_pname:
1567
   _mesa_unlock_texture(ctx, obj);
1568
   _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", pname);
1569
}
1570
 
1571
 
1572
void GLAPIENTRY
1573
_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
1574
{
1575
   struct gl_texture_object *obj;
1576
   GET_CURRENT_CONTEXT(ctx);
1577
 
1578
   obj = get_texobj(ctx, target, GL_TRUE);
1579
   if (!obj)
1580
      return;
1581
 
1582
   _mesa_lock_texture(ctx, obj);
1583
   switch (pname) {
1584
      case GL_TEXTURE_MAG_FILTER:
1585
         *params = (GLint) obj->Sampler.MagFilter;
1586
         break;
1587
      case GL_TEXTURE_MIN_FILTER:
1588
         *params = (GLint) obj->Sampler.MinFilter;
1589
         break;
1590
      case GL_TEXTURE_WRAP_S:
1591
         *params = (GLint) obj->Sampler.WrapS;
1592
         break;
1593
      case GL_TEXTURE_WRAP_T:
1594
         *params = (GLint) obj->Sampler.WrapT;
1595
         break;
1596
      case GL_TEXTURE_WRAP_R:
1597
         *params = (GLint) obj->Sampler.WrapR;
1598
         break;
1599
      case GL_TEXTURE_BORDER_COLOR:
1600
         if (!_mesa_is_desktop_gl(ctx))
1601
            goto invalid_pname;
1602
 
1603
         {
1604
            GLfloat b[4];
1605
            b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
1606
            b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
1607
            b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
1608
            b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
1609
            params[0] = FLOAT_TO_INT(b[0]);
1610
            params[1] = FLOAT_TO_INT(b[1]);
1611
            params[2] = FLOAT_TO_INT(b[2]);
1612
            params[3] = FLOAT_TO_INT(b[3]);
1613
         }
1614
         break;
1615
      case GL_TEXTURE_RESIDENT:
1616
         if (ctx->API != API_OPENGL_COMPAT)
1617
            goto invalid_pname;
1618
 
1619
         *params = 1;
1620
         break;
1621
      case GL_TEXTURE_PRIORITY:
1622
         if (ctx->API != API_OPENGL_COMPAT)
1623
            goto invalid_pname;
1624
 
1625
         *params = FLOAT_TO_INT(obj->Priority);
1626
         break;
1627
      case GL_TEXTURE_MIN_LOD:
1628
         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1629
            goto invalid_pname;
1630
 
1631
         *params = (GLint) obj->Sampler.MinLod;
1632
         break;
1633
      case GL_TEXTURE_MAX_LOD:
1634
         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1635
            goto invalid_pname;
1636
 
1637
         *params = (GLint) obj->Sampler.MaxLod;
1638
         break;
1639
      case GL_TEXTURE_BASE_LEVEL:
1640
         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1641
            goto invalid_pname;
1642
 
1643
         *params = obj->BaseLevel;
1644
         break;
1645
      case GL_TEXTURE_MAX_LEVEL:
1646
         *params = obj->MaxLevel;
1647
         break;
1648
      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1649
         if (!ctx->Extensions.EXT_texture_filter_anisotropic)
1650
            goto invalid_pname;
1651
         *params = (GLint) obj->Sampler.MaxAnisotropy;
1652
         break;
1653
      case GL_GENERATE_MIPMAP_SGIS:
1654
         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1655
            goto invalid_pname;
1656
 
1657
	 *params = (GLint) obj->GenerateMipmap;
1658
         break;
1659
      case GL_TEXTURE_COMPARE_MODE_ARB:
1660
         if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1661
             && !_mesa_is_gles3(ctx))
1662
            goto invalid_pname;
1663
         *params = (GLint) obj->Sampler.CompareMode;
1664
         break;
1665
      case GL_TEXTURE_COMPARE_FUNC_ARB:
1666
         if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1667
             && !_mesa_is_gles3(ctx))
1668
            goto invalid_pname;
1669
         *params = (GLint) obj->Sampler.CompareFunc;
1670
         break;
1671
      case GL_DEPTH_TEXTURE_MODE_ARB:
1672
         if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
1673
            goto invalid_pname;
1674
         *params = (GLint) obj->DepthMode;
1675
         break;
1676
      case GL_TEXTURE_LOD_BIAS:
4401 Serge 1677
         if (_mesa_is_gles(ctx))
4358 Serge 1678
            goto invalid_pname;
1679
 
4401 Serge 1680
         /* GL spec 'Data Conversions' section specifies that floating-point
1681
          * value in integer Get function is rounded to nearest integer
1682
          */
1683
         *params = (GLint) roundf(obj->Sampler.LodBias);
4358 Serge 1684
         break;
1685
      case GL_TEXTURE_CROP_RECT_OES:
1686
         if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
1687
            goto invalid_pname;
1688
 
1689
         params[0] = obj->CropRect[0];
1690
         params[1] = obj->CropRect[1];
1691
         params[2] = obj->CropRect[2];
1692
         params[3] = obj->CropRect[3];
1693
         break;
1694
      case GL_TEXTURE_SWIZZLE_R_EXT:
1695
      case GL_TEXTURE_SWIZZLE_G_EXT:
1696
      case GL_TEXTURE_SWIZZLE_B_EXT:
1697
      case GL_TEXTURE_SWIZZLE_A_EXT:
1698
         if ((!_mesa_is_desktop_gl(ctx)
1699
              || !ctx->Extensions.EXT_texture_swizzle)
1700
             && !_mesa_is_gles3(ctx))
1701
            goto invalid_pname;
1702
         *params = obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
1703
         break;
1704
 
1705
      case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1706
         if ((!_mesa_is_desktop_gl(ctx)
1707
              || !ctx->Extensions.EXT_texture_swizzle)
1708
             && !_mesa_is_gles3(ctx))
1709
            goto invalid_pname;
1710
         COPY_4V(params, obj->Swizzle);
1711
         break;
1712
 
1713
      case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1714
         if (!_mesa_is_desktop_gl(ctx)
1715
             || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
1716
            goto invalid_pname;
1717
         *params = (GLint) obj->Sampler.CubeMapSeamless;
1718
         break;
1719
 
1720
      case GL_TEXTURE_IMMUTABLE_FORMAT:
1721
         *params = (GLint) obj->Immutable;
1722
         break;
1723
 
1724
      case GL_TEXTURE_IMMUTABLE_LEVELS:
1725
         if (!_mesa_is_gles3(ctx))
1726
            goto invalid_pname;
1727
         *params = obj->ImmutableLevels;
1728
         break;
1729
 
1730
      case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
1731
         if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
1732
            goto invalid_pname;
1733
         *params = obj->RequiredTextureImageUnits;
1734
         break;
1735
 
1736
      case GL_TEXTURE_SRGB_DECODE_EXT:
1737
         if (!ctx->Extensions.EXT_texture_sRGB_decode)
1738
            goto invalid_pname;
1739
         *params = obj->Sampler.sRGBDecode;
1740
         break;
1741
 
1742
      default:
1743
         goto invalid_pname;
1744
   }
1745
 
1746
   /* no error if we get here */
1747
   _mesa_unlock_texture(ctx, obj);
1748
   return;
1749
 
1750
invalid_pname:
1751
   _mesa_unlock_texture(ctx, obj);
1752
   _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname);
1753
}
1754
 
1755
 
1756
/** New in GL 3.0 */
1757
void GLAPIENTRY
1758
_mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
1759
{
1760
   struct gl_texture_object *texObj;
1761
   GET_CURRENT_CONTEXT(ctx);
1762
 
1763
   texObj = get_texobj(ctx, target, GL_TRUE);
1764
   if (!texObj)
1765
      return;
1766
 
1767
   switch (pname) {
1768
   case GL_TEXTURE_BORDER_COLOR:
1769
      COPY_4V(params, texObj->Sampler.BorderColor.i);
1770
      break;
1771
   default:
1772
      _mesa_GetTexParameteriv(target, pname, params);
1773
   }
1774
}
1775
 
1776
 
1777
/** New in GL 3.0 */
1778
void GLAPIENTRY
1779
_mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
1780
{
1781
   struct gl_texture_object *texObj;
1782
   GET_CURRENT_CONTEXT(ctx);
1783
 
1784
   texObj = get_texobj(ctx, target, GL_TRUE);
1785
   if (!texObj)
1786
      return;
1787
 
1788
   switch (pname) {
1789
   case GL_TEXTURE_BORDER_COLOR:
1790
      COPY_4V(params, texObj->Sampler.BorderColor.i);
1791
      break;
1792
   default:
1793
      {
1794
         GLint ip[4];
1795
         _mesa_GetTexParameteriv(target, pname, ip);
1796
         params[0] = ip[0];
1797
         if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT ||
1798
             pname == GL_TEXTURE_CROP_RECT_OES) {
1799
            params[1] = ip[1];
1800
            params[2] = ip[2];
1801
            params[3] = ip[3];
1802
         }
1803
      }
1804
   }
1805
}