Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 1
/*
2
 * Mesa 3-D graphics library
3
 *
4
 * Copyright (C) 2011  VMware, Inc.  All Rights Reserved.
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10
 * and/or sell copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included
14
 * in all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
 * OTHER DEALINGS IN THE SOFTWARE.
23
 */
24
 
25
 
26
/**
27
 * \file samplerobj.c
28
 * \brief Functions for the GL_ARB_sampler_objects extension.
29
 * \author Brian Paul
30
 */
31
 
32
 
33
#include "main/glheader.h"
34
#include "main/context.h"
35
#include "main/dispatch.h"
36
#include "main/enums.h"
37
#include "main/hash.h"
38
#include "main/macros.h"
39
#include "main/mtypes.h"
40
#include "main/samplerobj.h"
41
 
42
 
43
struct gl_sampler_object *
44
_mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name)
45
{
46
   if (name == 0)
47
      return NULL;
48
   else
49
      return (struct gl_sampler_object *)
50
         _mesa_HashLookup(ctx->Shared->SamplerObjects, name);
51
}
52
 
53
 
54
static inline void
55
begin_samplerobj_lookups(struct gl_context *ctx)
56
{
57
   _mesa_HashLockMutex(ctx->Shared->SamplerObjects);
58
}
59
 
60
 
61
static inline void
62
end_samplerobj_lookups(struct gl_context *ctx)
63
{
64
   _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects);
65
}
66
 
67
 
68
static inline struct gl_sampler_object *
69
lookup_samplerobj_locked(struct gl_context *ctx, GLuint name)
70
{
71
   return (struct gl_sampler_object *)
72
         _mesa_HashLookupLocked(ctx->Shared->SamplerObjects, name);
73
}
74
 
75
 
76
/**
77
 * Handle reference counting.
78
 */
79
void
80
_mesa_reference_sampler_object_(struct gl_context *ctx,
81
                                struct gl_sampler_object **ptr,
82
                                struct gl_sampler_object *samp)
83
{
84
   assert(*ptr != samp); /* The inline wrapper should prevent no-op calls */
85
 
86
   if (*ptr) {
87
      /* Unreference the old sampler */
88
      GLboolean deleteFlag = GL_FALSE;
89
      struct gl_sampler_object *oldSamp = *ptr;
90
 
91
      /*mtx_lock(&oldSamp->Mutex);*/
92
      assert(oldSamp->RefCount > 0);
93
      oldSamp->RefCount--;
94
#if 0
95
      printf("SamplerObj %p %d DECR to %d\n",
96
             (void *) oldSamp, oldSamp->Name, oldSamp->RefCount);
97
#endif
98
      deleteFlag = (oldSamp->RefCount == 0);
99
      /*mtx_unlock(&oldSamp->Mutex);*/
100
 
101
      if (deleteFlag) {
102
	 assert(ctx->Driver.DeleteSamplerObject);
103
         ctx->Driver.DeleteSamplerObject(ctx, oldSamp);
104
      }
105
 
106
      *ptr = NULL;
107
   }
108
   assert(!*ptr);
109
 
110
   if (samp) {
111
      /* reference new sampler */
112
      /*mtx_lock(&samp->Mutex);*/
113
      if (samp->RefCount == 0) {
114
         /* this sampler's being deleted (look just above) */
115
         /* Not sure this can every really happen.  Warn if it does. */
116
         _mesa_problem(NULL, "referencing deleted sampler object");
117
         *ptr = NULL;
118
      }
119
      else {
120
         samp->RefCount++;
121
#if 0
122
         printf("SamplerObj %p %d INCR to %d\n",
123
                (void *) samp, samp->Name, samp->RefCount);
124
#endif
125
         *ptr = samp;
126
      }
127
      /*mtx_unlock(&samp->Mutex);*/
128
   }
129
}
130
 
131
 
132
/**
133
 * Initialize the fields of the given sampler object.
134
 */
135
static void
136
_mesa_init_sampler_object(struct gl_sampler_object *sampObj, GLuint name)
137
{
138
   sampObj->Name = name;
139
   sampObj->RefCount = 1;
140
   sampObj->WrapS = GL_REPEAT;
141
   sampObj->WrapT = GL_REPEAT;
142
   sampObj->WrapR = GL_REPEAT;
143
   sampObj->MinFilter = GL_NEAREST_MIPMAP_LINEAR;
144
   sampObj->MagFilter = GL_LINEAR;
145
   sampObj->BorderColor.f[0] = 0.0;
146
   sampObj->BorderColor.f[1] = 0.0;
147
   sampObj->BorderColor.f[2] = 0.0;
148
   sampObj->BorderColor.f[3] = 0.0;
149
   sampObj->MinLod = -1000.0F;
150
   sampObj->MaxLod = 1000.0F;
151
   sampObj->LodBias = 0.0F;
152
   sampObj->MaxAnisotropy = 1.0F;
153
   sampObj->CompareMode = GL_NONE;
154
   sampObj->CompareFunc = GL_LEQUAL;
155
   sampObj->sRGBDecode = GL_DECODE_EXT;
156
   sampObj->CubeMapSeamless = GL_FALSE;
157
}
158
 
159
/**
160
 * Fallback for ctx->Driver.NewSamplerObject();
161
 */
162
struct gl_sampler_object *
163
_mesa_new_sampler_object(struct gl_context *ctx, GLuint name)
164
{
165
   struct gl_sampler_object *sampObj = CALLOC_STRUCT(gl_sampler_object);
166
   if (sampObj) {
167
      _mesa_init_sampler_object(sampObj, name);
168
   }
169
   return sampObj;
170
}
171
 
172
 
173
/**
174
 * Fallback for ctx->Driver.DeleteSamplerObject();
175
 */
176
static void
177
_mesa_delete_sampler_object(struct gl_context *ctx,
178
                            struct gl_sampler_object *sampObj)
179
{
180
   free(sampObj->Label);
181
   free(sampObj);
182
}
183
 
184
static void
185
create_samplers(struct gl_context *ctx, GLsizei count, GLuint *samplers,
186
                const char *caller)
187
{
188
   GLuint first;
189
   GLint i;
190
 
191
   if (MESA_VERBOSE & VERBOSE_API)
192
      _mesa_debug(ctx, "%s(%d)\n", caller, count);
193
 
194
   if (count < 0) {
195
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n<0)", caller);
196
      return;
197
   }
198
 
199
   if (!samplers)
200
      return;
201
 
202
   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->SamplerObjects, count);
203
 
204
   /* Insert the ID and pointer to new sampler object into hash table */
205
   for (i = 0; i < count; i++) {
206
      struct gl_sampler_object *sampObj =
207
         ctx->Driver.NewSamplerObject(ctx, first + i);
208
      _mesa_HashInsert(ctx->Shared->SamplerObjects, first + i, sampObj);
209
      samplers[i] = first + i;
210
   }
211
}
212
 
213
void GLAPIENTRY
214
_mesa_GenSamplers(GLsizei count, GLuint *samplers)
215
{
216
   GET_CURRENT_CONTEXT(ctx);
217
   create_samplers(ctx, count, samplers, "glGenSamplers");
218
}
219
 
220
void GLAPIENTRY
221
_mesa_CreateSamplers(GLsizei count, GLuint *samplers)
222
{
223
   GET_CURRENT_CONTEXT(ctx);
224
 
225
   if (!ctx->Extensions.ARB_direct_state_access) {
226
      _mesa_error(ctx, GL_INVALID_OPERATION, "glCreateSamplers("
227
                  "GL_ARB_direct_state_access is not supported)");
228
      return;
229
   }
230
 
231
   create_samplers(ctx, count, samplers, "glCreateSamplers");
232
}
233
 
234
 
235
void GLAPIENTRY
236
_mesa_DeleteSamplers(GLsizei count, const GLuint *samplers)
237
{
238
   GET_CURRENT_CONTEXT(ctx);
239
   GLsizei i;
240
 
241
   FLUSH_VERTICES(ctx, 0);
242
 
243
   if (count < 0) {
244
      _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteSamplers(count)");
245
      return;
246
   }
247
 
248
   mtx_lock(&ctx->Shared->Mutex);
249
 
250
   for (i = 0; i < count; i++) {
251
      if (samplers[i]) {
252
         GLuint j;
253
         struct gl_sampler_object *sampObj =
254
            _mesa_lookup_samplerobj(ctx, samplers[i]);
255
 
256
         if (sampObj) {
257
            /* If the sampler is currently bound, unbind it. */
258
            for (j = 0; j < ctx->Const.MaxCombinedTextureImageUnits; j++) {
259
               if (ctx->Texture.Unit[j].Sampler == sampObj) {
260
                  FLUSH_VERTICES(ctx, _NEW_TEXTURE);
261
                  _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[j].Sampler, NULL);
262
               }
263
            }
264
 
265
            /* The ID is immediately freed for re-use */
266
            _mesa_HashRemove(ctx->Shared->SamplerObjects, samplers[i]);
267
            /* But the object exists until its reference count goes to zero */
268
            _mesa_reference_sampler_object(ctx, &sampObj, NULL);
269
         }
270
      }
271
   }
272
 
273
   mtx_unlock(&ctx->Shared->Mutex);
274
}
275
 
276
 
277
GLboolean GLAPIENTRY
278
_mesa_IsSampler(GLuint sampler)
279
{
280
   struct gl_sampler_object *sampObj;
281
   GET_CURRENT_CONTEXT(ctx);
282
 
283
   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
284
 
285
   if (sampler == 0)
286
      return GL_FALSE;
287
 
288
   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
289
 
290
   return sampObj != NULL;
291
}
292
 
293
 
294
void GLAPIENTRY
295
_mesa_BindSampler(GLuint unit, GLuint sampler)
296
{
297
   struct gl_sampler_object *sampObj;
298
   GET_CURRENT_CONTEXT(ctx);
299
 
300
   if (unit >= ctx->Const.MaxCombinedTextureImageUnits) {
301
      _mesa_error(ctx, GL_INVALID_VALUE, "glBindSampler(unit %u)", unit);
302
      return;
303
   }
304
 
305
   if (sampler == 0) {
306
      /* Use the default sampler object, the one contained in the texture
307
       * object.
308
       */
309
      sampObj = NULL;
310
   }
311
   else {
312
      /* user-defined sampler object */
313
      sampObj = _mesa_lookup_samplerobj(ctx, sampler);
314
      if (!sampObj) {
315
         _mesa_error(ctx, GL_INVALID_OPERATION, "glBindSampler(sampler)");
316
         return;
317
      }
318
   }
319
 
320
   if (ctx->Texture.Unit[unit].Sampler != sampObj) {
321
      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
322
   }
323
 
324
   /* bind new sampler */
325
   _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[unit].Sampler,
326
                                  sampObj);
327
}
328
 
329
 
330
void GLAPIENTRY
331
_mesa_BindSamplers(GLuint first, GLsizei count, const GLuint *samplers)
332
{
333
   GET_CURRENT_CONTEXT(ctx);
334
   GLint i;
335
 
336
   /* The ARB_multi_bind spec says:
337
    *
338
    *   "An INVALID_OPERATION error is generated if  +  is
339
    *    greater than the number of texture image units supported by
340
    *    the implementation."
341
    */
342
   if (first + count > ctx->Const.MaxCombinedTextureImageUnits) {
343
      _mesa_error(ctx, GL_INVALID_OPERATION,
344
                  "glBindSamplers(first=%u + count=%d > the value of "
345
                  "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS=%u)",
346
                  first, count, ctx->Const.MaxCombinedTextureImageUnits);
347
      return;
348
   }
349
 
350
   FLUSH_VERTICES(ctx, 0);
351
 
352
   if (samplers) {
353
      /* Note that the error semantics for multi-bind commands differ from
354
       * those of other GL commands.
355
       *
356
       * The Issues section in the ARB_multi_bind spec says:
357
       *
358
       *    "(11) Typically, OpenGL specifies that if an error is generated by
359
       *          a command, that command has no effect.  This is somewhat
360
       *          unfortunate for multi-bind commands, because it would require
361
       *          a first pass to scan the entire list of bound objects for
362
       *          errors and then a second pass to actually perform the
363
       *          bindings.  Should we have different error semantics?
364
       *
365
       *       RESOLVED:  Yes.  In this specification, when the parameters for
366
       *       one of the  binding points are invalid, that binding
367
       *       point is not updated and an error will be generated.  However,
368
       *       other binding points in the same command will be updated if
369
       *       their parameters are valid and no other error occurs."
370
       */
371
 
372
      begin_samplerobj_lookups(ctx);
373
 
374
      for (i = 0; i < count; i++) {
375
         const GLuint unit = first + i;
376
         struct gl_sampler_object * const currentSampler =
377
             ctx->Texture.Unit[unit].Sampler;
378
         struct gl_sampler_object *sampObj;
379
 
380
         if (samplers[i] != 0) {
381
            if (currentSampler && currentSampler->Name == samplers[i])
382
               sampObj = currentSampler;
383
            else
384
               sampObj = lookup_samplerobj_locked(ctx, samplers[i]);
385
 
386
            /* The ARB_multi_bind spec says:
387
             *
388
             *    "An INVALID_OPERATION error is generated if any value
389
             *     in  is not zero or the name of an existing
390
             *     sampler object (per binding)."
391
             */
392
            if (!sampObj) {
393
               _mesa_error(ctx, GL_INVALID_OPERATION,
394
                           "glBindSamplers(samplers[%d]=%u is not zero or "
395
                           "the name of an existing sampler object)",
396
                           i, samplers[i]);
397
               continue;
398
            }
399
         } else {
400
            sampObj = NULL;
401
         }
402
 
403
         /* Bind the new sampler */
404
         if (sampObj != currentSampler) {
405
            _mesa_reference_sampler_object(ctx,
406
                                           &ctx->Texture.Unit[unit].Sampler,
407
                                           sampObj);
408
            ctx->NewState |= _NEW_TEXTURE;
409
         }
410
      }
411
 
412
      end_samplerobj_lookups(ctx);
413
   } else {
414
      /* Unbind all samplers in the range  through +-1 */
415
      for (i = 0; i < count; i++) {
416
         const GLuint unit = first + i;
417
 
418
         if (ctx->Texture.Unit[unit].Sampler) {
419
            _mesa_reference_sampler_object(ctx,
420
                                           &ctx->Texture.Unit[unit].Sampler,
421
                                           NULL);
422
            ctx->NewState |= _NEW_TEXTURE;
423
         }
424
      }
425
   }
426
}
427
 
428
 
429
/**
430
 * Check if a coordinate wrap mode is legal.
431
 * \return GL_TRUE if legal, GL_FALSE otherwise
432
 */
433
static GLboolean
434
validate_texture_wrap_mode(struct gl_context *ctx, GLenum wrap)
435
{
436
   const struct gl_extensions * const e = &ctx->Extensions;
437
 
438
   switch (wrap) {
439
   case GL_CLAMP:
440
   case GL_CLAMP_TO_EDGE:
441
   case GL_REPEAT:
442
   case GL_MIRRORED_REPEAT:
443
      return GL_TRUE;
444
   case GL_CLAMP_TO_BORDER:
445
      return e->ARB_texture_border_clamp;
446
   case GL_MIRROR_CLAMP_EXT:
447
      return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp;
448
   case GL_MIRROR_CLAMP_TO_EDGE_EXT:
449
      return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp || e->ARB_texture_mirror_clamp_to_edge;
450
   case GL_MIRROR_CLAMP_TO_BORDER_EXT:
451
      return e->EXT_texture_mirror_clamp;
452
   default:
453
      return GL_FALSE;
454
   }
455
}
456
 
457
 
458
/**
459
 * This is called just prior to changing any sampler object state.
460
 */
461
static inline void
462
flush(struct gl_context *ctx)
463
{
464
   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
465
}
466
 
467
 
468
#define INVALID_PARAM 0x100
469
#define INVALID_PNAME 0x101
470
#define INVALID_VALUE 0x102
471
 
472
static GLuint
473
set_sampler_wrap_s(struct gl_context *ctx, struct gl_sampler_object *samp,
474
                   GLint param)
475
{
476
   if (samp->WrapS == param)
477
      return GL_FALSE;
478
   if (validate_texture_wrap_mode(ctx, param)) {
479
      flush(ctx);
480
      samp->WrapS = param;
481
      return GL_TRUE;
482
   }
483
   return INVALID_PARAM;
484
}
485
 
486
 
487
static GLuint
488
set_sampler_wrap_t(struct gl_context *ctx, struct gl_sampler_object *samp,
489
                   GLint param)
490
{
491
   if (samp->WrapT == param)
492
      return GL_FALSE;
493
   if (validate_texture_wrap_mode(ctx, param)) {
494
      flush(ctx);
495
      samp->WrapT = param;
496
      return GL_TRUE;
497
   }
498
   return INVALID_PARAM;
499
}
500
 
501
 
502
static GLuint
503
set_sampler_wrap_r(struct gl_context *ctx, struct gl_sampler_object *samp,
504
                   GLint param)
505
{
506
   if (samp->WrapR == param)
507
      return GL_FALSE;
508
   if (validate_texture_wrap_mode(ctx, param)) {
509
      flush(ctx);
510
      samp->WrapR = param;
511
      return GL_TRUE;
512
   }
513
   return INVALID_PARAM;
514
}
515
 
516
 
517
static GLuint
518
set_sampler_min_filter(struct gl_context *ctx, struct gl_sampler_object *samp,
519
                       GLint param)
520
{
521
   if (samp->MinFilter == param)
522
      return GL_FALSE;
523
 
524
   switch (param) {
525
   case GL_NEAREST:
526
   case GL_LINEAR:
527
   case GL_NEAREST_MIPMAP_NEAREST:
528
   case GL_LINEAR_MIPMAP_NEAREST:
529
   case GL_NEAREST_MIPMAP_LINEAR:
530
   case GL_LINEAR_MIPMAP_LINEAR:
531
      flush(ctx);
532
      samp->MinFilter = param;
533
      return GL_TRUE;
534
   default:
535
      return INVALID_PARAM;
536
   }
537
}
538
 
539
 
540
static GLuint
541
set_sampler_mag_filter(struct gl_context *ctx, struct gl_sampler_object *samp,
542
                       GLint param)
543
{
544
   if (samp->MagFilter == param)
545
      return GL_FALSE;
546
 
547
   switch (param) {
548
   case GL_NEAREST:
549
   case GL_LINEAR:
550
      flush(ctx);
551
      samp->MagFilter = param;
552
      return GL_TRUE;
553
   default:
554
      return INVALID_PARAM;
555
   }
556
}
557
 
558
 
559
static GLuint
560
set_sampler_lod_bias(struct gl_context *ctx, struct gl_sampler_object *samp,
561
                     GLfloat param)
562
{
563
   if (samp->LodBias == param)
564
      return GL_FALSE;
565
 
566
   flush(ctx);
567
   samp->LodBias = param;
568
   return GL_TRUE;
569
}
570
 
571
 
572
static GLuint
573
set_sampler_border_colorf(struct gl_context *ctx,
574
                          struct gl_sampler_object *samp,
575
                          const GLfloat params[4])
576
{
577
   flush(ctx);
578
   samp->BorderColor.f[RCOMP] = params[0];
579
   samp->BorderColor.f[GCOMP] = params[1];
580
   samp->BorderColor.f[BCOMP] = params[2];
581
   samp->BorderColor.f[ACOMP] = params[3];
582
   return GL_TRUE;
583
}
584
 
585
 
586
static GLuint
587
set_sampler_border_colori(struct gl_context *ctx,
588
                          struct gl_sampler_object *samp,
589
                          const GLint params[4])
590
{
591
   flush(ctx);
592
   samp->BorderColor.i[RCOMP] = params[0];
593
   samp->BorderColor.i[GCOMP] = params[1];
594
   samp->BorderColor.i[BCOMP] = params[2];
595
   samp->BorderColor.i[ACOMP] = params[3];
596
   return GL_TRUE;
597
}
598
 
599
 
600
static GLuint
601
set_sampler_border_colorui(struct gl_context *ctx,
602
                           struct gl_sampler_object *samp,
603
                           const GLuint params[4])
604
{
605
   flush(ctx);
606
   samp->BorderColor.ui[RCOMP] = params[0];
607
   samp->BorderColor.ui[GCOMP] = params[1];
608
   samp->BorderColor.ui[BCOMP] = params[2];
609
   samp->BorderColor.ui[ACOMP] = params[3];
610
   return GL_TRUE;
611
}
612
 
613
 
614
static GLuint
615
set_sampler_min_lod(struct gl_context *ctx, struct gl_sampler_object *samp,
616
                    GLfloat param)
617
{
618
   if (samp->MinLod == param)
619
      return GL_FALSE;
620
 
621
   flush(ctx);
622
   samp->MinLod = param;
623
   return GL_TRUE;
624
}
625
 
626
 
627
static GLuint
628
set_sampler_max_lod(struct gl_context *ctx, struct gl_sampler_object *samp,
629
                    GLfloat param)
630
{
631
   if (samp->MaxLod == param)
632
      return GL_FALSE;
633
 
634
   flush(ctx);
635
   samp->MaxLod = param;
636
   return GL_TRUE;
637
}
638
 
639
 
640
static GLuint
641
set_sampler_compare_mode(struct gl_context *ctx,
642
                         struct gl_sampler_object *samp, GLint param)
643
{
644
   if (!ctx->Extensions.ARB_shadow)
645
      return INVALID_PNAME;
646
 
647
   if (samp->CompareMode == param)
648
      return GL_FALSE;
649
 
650
   if (param == GL_NONE ||
651
       param == GL_COMPARE_R_TO_TEXTURE_ARB) {
652
      flush(ctx);
653
      samp->CompareMode = param;
654
      return GL_TRUE;
655
   }
656
 
657
   return INVALID_PARAM;
658
}
659
 
660
 
661
static GLuint
662
set_sampler_compare_func(struct gl_context *ctx,
663
                         struct gl_sampler_object *samp, GLint param)
664
{
665
   if (!ctx->Extensions.ARB_shadow)
666
      return INVALID_PNAME;
667
 
668
   if (samp->CompareFunc == param)
669
      return GL_FALSE;
670
 
671
   switch (param) {
672
   case GL_LEQUAL:
673
   case GL_GEQUAL:
674
   case GL_EQUAL:
675
   case GL_NOTEQUAL:
676
   case GL_LESS:
677
   case GL_GREATER:
678
   case GL_ALWAYS:
679
   case GL_NEVER:
680
      flush(ctx);
681
      samp->CompareFunc = param;
682
      return GL_TRUE;
683
   default:
684
      return INVALID_PARAM;
685
   }
686
}
687
 
688
 
689
static GLuint
690
set_sampler_max_anisotropy(struct gl_context *ctx,
691
                           struct gl_sampler_object *samp, GLfloat param)
692
{
693
   if (!ctx->Extensions.EXT_texture_filter_anisotropic)
694
      return INVALID_PNAME;
695
 
696
   if (samp->MaxAnisotropy == param)
697
      return GL_FALSE;
698
 
699
   if (param < 1.0)
700
      return INVALID_VALUE;
701
 
702
   flush(ctx);
703
   /* clamp to max, that's what NVIDIA does */
704
   samp->MaxAnisotropy = MIN2(param, ctx->Const.MaxTextureMaxAnisotropy);
705
   return GL_TRUE;
706
}
707
 
708
 
709
static GLuint
710
set_sampler_cube_map_seamless(struct gl_context *ctx,
711
                              struct gl_sampler_object *samp, GLboolean param)
712
{
713
   if (!_mesa_is_desktop_gl(ctx)
714
       || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
715
      return INVALID_PNAME;
716
 
717
   if (samp->CubeMapSeamless == param)
718
      return GL_FALSE;
719
 
720
   if (param != GL_TRUE && param != GL_FALSE)
721
      return INVALID_VALUE;
722
 
723
   flush(ctx);
724
   samp->CubeMapSeamless = param;
725
   return GL_TRUE;
726
}
727
 
728
static GLuint
729
set_sampler_srgb_decode(struct gl_context *ctx,
730
                              struct gl_sampler_object *samp, GLenum param)
731
{
732
   if (!ctx->Extensions.EXT_texture_sRGB_decode)
733
      return INVALID_PNAME;
734
 
735
   if (samp->sRGBDecode == param)
736
      return GL_FALSE;
737
 
738
   if (param != GL_DECODE_EXT && param != GL_SKIP_DECODE_EXT)
739
      return INVALID_VALUE;
740
 
741
   flush(ctx);
742
   samp->sRGBDecode = param;
743
   return GL_TRUE;
744
}
745
 
746
void GLAPIENTRY
747
_mesa_SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
748
{
749
   struct gl_sampler_object *sampObj;
750
   GLuint res;
751
   GET_CURRENT_CONTEXT(ctx);
752
 
753
   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
754
   if (!sampObj) {
755
      /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states:
756
       *
757
       *     "An INVALID_OPERATION error is generated if sampler is not the name
758
       *     of a sampler object previously returned from a call to GenSamplers."
759
       *
760
       * In desktop GL, an GL_INVALID_VALUE is returned instead.
761
       */
762
      _mesa_error(ctx, (_mesa_is_gles(ctx) ?
763
                        GL_INVALID_OPERATION : GL_INVALID_VALUE),
764
                  "glSamplerParameteri(sampler %u)", sampler);
765
      return;
766
   }
767
 
768
   switch (pname) {
769
   case GL_TEXTURE_WRAP_S:
770
      res = set_sampler_wrap_s(ctx, sampObj, param);
771
      break;
772
   case GL_TEXTURE_WRAP_T:
773
      res = set_sampler_wrap_t(ctx, sampObj, param);
774
      break;
775
   case GL_TEXTURE_WRAP_R:
776
      res = set_sampler_wrap_r(ctx, sampObj, param);
777
      break;
778
   case GL_TEXTURE_MIN_FILTER:
779
      res = set_sampler_min_filter(ctx, sampObj, param);
780
      break;
781
   case GL_TEXTURE_MAG_FILTER:
782
      res = set_sampler_mag_filter(ctx, sampObj, param);
783
      break;
784
   case GL_TEXTURE_MIN_LOD:
785
      res = set_sampler_min_lod(ctx, sampObj, (GLfloat) param);
786
      break;
787
   case GL_TEXTURE_MAX_LOD:
788
      res = set_sampler_max_lod(ctx, sampObj, (GLfloat) param);
789
      break;
790
   case GL_TEXTURE_LOD_BIAS:
791
      res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) param);
792
      break;
793
   case GL_TEXTURE_COMPARE_MODE:
794
      res = set_sampler_compare_mode(ctx, sampObj, param);
795
      break;
796
   case GL_TEXTURE_COMPARE_FUNC:
797
      res = set_sampler_compare_func(ctx, sampObj, param);
798
      break;
799
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
800
      res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) param);
801
      break;
802
   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
803
      res = set_sampler_cube_map_seamless(ctx, sampObj, param);
804
      break;
805
   case GL_TEXTURE_SRGB_DECODE_EXT:
806
      res = set_sampler_srgb_decode(ctx, sampObj, param);
807
      break;
808
   case GL_TEXTURE_BORDER_COLOR:
809
      /* fall-through */
810
   default:
811
      res = INVALID_PNAME;
812
   }
813
 
814
   switch (res) {
815
   case GL_FALSE:
816
      /* no change */
817
      break;
818
   case GL_TRUE:
819
      /* state change - we do nothing special at this time */
820
      break;
821
   case INVALID_PNAME:
822
      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(pname=%s)\n",
823
                  _mesa_lookup_enum_by_nr(pname));
824
      break;
825
   case INVALID_PARAM:
826
      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(param=%d)\n",
827
                  param);
828
      break;
829
   case INVALID_VALUE:
830
      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteri(param=%d)\n",
831
                  param);
832
      break;
833
   default:
834
      ;
835
   }
836
}
837
 
838
 
839
void GLAPIENTRY
840
_mesa_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
841
{
842
   struct gl_sampler_object *sampObj;
843
   GLuint res;
844
   GET_CURRENT_CONTEXT(ctx);
845
 
846
   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
847
   if (!sampObj) {
848
      /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states:
849
       *
850
       *     "An INVALID_OPERATION error is generated if sampler is not the name
851
       *     of a sampler object previously returned from a call to GenSamplers."
852
       *
853
       * In desktop GL, an GL_INVALID_VALUE is returned instead.
854
       */
855
      _mesa_error(ctx, (_mesa_is_gles(ctx) ?
856
                        GL_INVALID_OPERATION : GL_INVALID_VALUE),
857
                  "glSamplerParameterf(sampler %u)", sampler);
858
      return;
859
   }
860
 
861
   switch (pname) {
862
   case GL_TEXTURE_WRAP_S:
863
      res = set_sampler_wrap_s(ctx, sampObj, (GLint) param);
864
      break;
865
   case GL_TEXTURE_WRAP_T:
866
      res = set_sampler_wrap_t(ctx, sampObj, (GLint) param);
867
      break;
868
   case GL_TEXTURE_WRAP_R:
869
      res = set_sampler_wrap_r(ctx, sampObj, (GLint) param);
870
      break;
871
   case GL_TEXTURE_MIN_FILTER:
872
      res = set_sampler_min_filter(ctx, sampObj, (GLint) param);
873
      break;
874
   case GL_TEXTURE_MAG_FILTER:
875
      res = set_sampler_mag_filter(ctx, sampObj, (GLint) param);
876
      break;
877
   case GL_TEXTURE_MIN_LOD:
878
      res = set_sampler_min_lod(ctx, sampObj, param);
879
      break;
880
   case GL_TEXTURE_MAX_LOD:
881
      res = set_sampler_max_lod(ctx, sampObj, param);
882
      break;
883
   case GL_TEXTURE_LOD_BIAS:
884
      res = set_sampler_lod_bias(ctx, sampObj, param);
885
      break;
886
   case GL_TEXTURE_COMPARE_MODE:
887
      res = set_sampler_compare_mode(ctx, sampObj, (GLint) param);
888
      break;
889
   case GL_TEXTURE_COMPARE_FUNC:
890
      res = set_sampler_compare_func(ctx, sampObj, (GLint) param);
891
      break;
892
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
893
      res = set_sampler_max_anisotropy(ctx, sampObj, param);
894
      break;
895
   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
896
      res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) param);
897
      break;
898
   case GL_TEXTURE_SRGB_DECODE_EXT:
899
      res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) param);
900
      break;
901
   case GL_TEXTURE_BORDER_COLOR:
902
      /* fall-through */
903
   default:
904
      res = INVALID_PNAME;
905
   }
906
 
907
   switch (res) {
908
   case GL_FALSE:
909
      /* no change */
910
      break;
911
   case GL_TRUE:
912
      /* state change - we do nothing special at this time */
913
      break;
914
   case INVALID_PNAME:
915
      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(pname=%s)\n",
916
                  _mesa_lookup_enum_by_nr(pname));
917
      break;
918
   case INVALID_PARAM:
919
      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(param=%f)\n",
920
                  param);
921
      break;
922
   case INVALID_VALUE:
923
      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterf(param=%f)\n",
924
                  param);
925
      break;
926
   default:
927
      ;
928
   }
929
}
930
 
931
void GLAPIENTRY
932
_mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params)
933
{
934
   struct gl_sampler_object *sampObj;
935
   GLuint res;
936
   GET_CURRENT_CONTEXT(ctx);
937
 
938
   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
939
   if (!sampObj) {
940
      /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states:
941
       *
942
       *     "An INVALID_OPERATION error is generated if sampler is not the name
943
       *     of a sampler object previously returned from a call to GenSamplers."
944
       *
945
       * In desktop GL, an GL_INVALID_VALUE is returned instead.
946
       */
947
      _mesa_error(ctx, (_mesa_is_gles(ctx) ?
948
                        GL_INVALID_OPERATION : GL_INVALID_VALUE),
949
                  "glSamplerParameteriv(sampler %u)", sampler);
950
      return;
951
   }
952
 
953
   switch (pname) {
954
   case GL_TEXTURE_WRAP_S:
955
      res = set_sampler_wrap_s(ctx, sampObj, params[0]);
956
      break;
957
   case GL_TEXTURE_WRAP_T:
958
      res = set_sampler_wrap_t(ctx, sampObj, params[0]);
959
      break;
960
   case GL_TEXTURE_WRAP_R:
961
      res = set_sampler_wrap_r(ctx, sampObj, params[0]);
962
      break;
963
   case GL_TEXTURE_MIN_FILTER:
964
      res = set_sampler_min_filter(ctx, sampObj, params[0]);
965
      break;
966
   case GL_TEXTURE_MAG_FILTER:
967
      res = set_sampler_mag_filter(ctx, sampObj, params[0]);
968
      break;
969
   case GL_TEXTURE_MIN_LOD:
970
      res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]);
971
      break;
972
   case GL_TEXTURE_MAX_LOD:
973
      res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]);
974
      break;
975
   case GL_TEXTURE_LOD_BIAS:
976
      res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]);
977
      break;
978
   case GL_TEXTURE_COMPARE_MODE:
979
      res = set_sampler_compare_mode(ctx, sampObj, params[0]);
980
      break;
981
   case GL_TEXTURE_COMPARE_FUNC:
982
      res = set_sampler_compare_func(ctx, sampObj, params[0]);
983
      break;
984
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
985
      res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]);
986
      break;
987
   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
988
      res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]);
989
      break;
990
   case GL_TEXTURE_SRGB_DECODE_EXT:
991
      res = set_sampler_srgb_decode(ctx, sampObj, params[0]);
992
      break;
993
   case GL_TEXTURE_BORDER_COLOR:
994
      {
995
         GLfloat c[4];
996
         c[0] = INT_TO_FLOAT(params[0]);
997
         c[1] = INT_TO_FLOAT(params[1]);
998
         c[2] = INT_TO_FLOAT(params[2]);
999
         c[3] = INT_TO_FLOAT(params[3]);
1000
         res = set_sampler_border_colorf(ctx, sampObj, c);
1001
      }
1002
      break;
1003
   default:
1004
      res = INVALID_PNAME;
1005
   }
1006
 
1007
   switch (res) {
1008
   case GL_FALSE:
1009
      /* no change */
1010
      break;
1011
   case GL_TRUE:
1012
      /* state change - we do nothing special at this time */
1013
      break;
1014
   case INVALID_PNAME:
1015
      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(pname=%s)\n",
1016
                  _mesa_lookup_enum_by_nr(pname));
1017
      break;
1018
   case INVALID_PARAM:
1019
      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(param=%d)\n",
1020
                  params[0]);
1021
      break;
1022
   case INVALID_VALUE:
1023
      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteriv(param=%d)\n",
1024
                  params[0]);
1025
      break;
1026
   default:
1027
      ;
1028
   }
1029
}
1030
 
1031
void GLAPIENTRY
1032
_mesa_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params)
1033
{
1034
   struct gl_sampler_object *sampObj;
1035
   GLuint res;
1036
   GET_CURRENT_CONTEXT(ctx);
1037
 
1038
   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1039
   if (!sampObj) {
1040
      /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states:
1041
       *
1042
       *     "An INVALID_OPERATION error is generated if sampler is not the name
1043
       *     of a sampler object previously returned from a call to GenSamplers."
1044
       *
1045
       * In desktop GL, an GL_INVALID_VALUE is returned instead.
1046
       */
1047
      _mesa_error(ctx, (_mesa_is_gles(ctx) ?
1048
                        GL_INVALID_OPERATION : GL_INVALID_VALUE),
1049
                  "glSamplerParameterfv(sampler %u)", sampler);
1050
      return;
1051
   }
1052
 
1053
   switch (pname) {
1054
   case GL_TEXTURE_WRAP_S:
1055
      res = set_sampler_wrap_s(ctx, sampObj, (GLint) params[0]);
1056
      break;
1057
   case GL_TEXTURE_WRAP_T:
1058
      res = set_sampler_wrap_t(ctx, sampObj, (GLint) params[0]);
1059
      break;
1060
   case GL_TEXTURE_WRAP_R:
1061
      res = set_sampler_wrap_r(ctx, sampObj, (GLint) params[0]);
1062
      break;
1063
   case GL_TEXTURE_MIN_FILTER:
1064
      res = set_sampler_min_filter(ctx, sampObj, (GLint) params[0]);
1065
      break;
1066
   case GL_TEXTURE_MAG_FILTER:
1067
      res = set_sampler_mag_filter(ctx, sampObj, (GLint) params[0]);
1068
      break;
1069
   case GL_TEXTURE_MIN_LOD:
1070
      res = set_sampler_min_lod(ctx, sampObj, params[0]);
1071
      break;
1072
   case GL_TEXTURE_MAX_LOD:
1073
      res = set_sampler_max_lod(ctx, sampObj, params[0]);
1074
      break;
1075
   case GL_TEXTURE_LOD_BIAS:
1076
      res = set_sampler_lod_bias(ctx, sampObj, params[0]);
1077
      break;
1078
   case GL_TEXTURE_COMPARE_MODE:
1079
      res = set_sampler_compare_mode(ctx, sampObj, (GLint) params[0]);
1080
      break;
1081
   case GL_TEXTURE_COMPARE_FUNC:
1082
      res = set_sampler_compare_func(ctx, sampObj, (GLint) params[0]);
1083
      break;
1084
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1085
      res = set_sampler_max_anisotropy(ctx, sampObj, params[0]);
1086
      break;
1087
   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1088
      res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) params[0]);
1089
      break;
1090
   case GL_TEXTURE_SRGB_DECODE_EXT:
1091
      res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]);
1092
      break;
1093
   case GL_TEXTURE_BORDER_COLOR:
1094
      res = set_sampler_border_colorf(ctx, sampObj, params);
1095
      break;
1096
   default:
1097
      res = INVALID_PNAME;
1098
   }
1099
 
1100
   switch (res) {
1101
   case GL_FALSE:
1102
      /* no change */
1103
      break;
1104
   case GL_TRUE:
1105
      /* state change - we do nothing special at this time */
1106
      break;
1107
   case INVALID_PNAME:
1108
      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(pname=%s)\n",
1109
                  _mesa_lookup_enum_by_nr(pname));
1110
      break;
1111
   case INVALID_PARAM:
1112
      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(param=%f)\n",
1113
                  params[0]);
1114
      break;
1115
   case INVALID_VALUE:
1116
      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterfv(param=%f)\n",
1117
                  params[0]);
1118
      break;
1119
   default:
1120
      ;
1121
   }
1122
}
1123
 
1124
void GLAPIENTRY
1125
_mesa_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params)
1126
{
1127
   struct gl_sampler_object *sampObj;
1128
   GLuint res;
1129
   GET_CURRENT_CONTEXT(ctx);
1130
 
1131
   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1132
   if (!sampObj) {
1133
      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(sampler %u)",
1134
                  sampler);
1135
      return;
1136
   }
1137
 
1138
   switch (pname) {
1139
   case GL_TEXTURE_WRAP_S:
1140
      res = set_sampler_wrap_s(ctx, sampObj, params[0]);
1141
      break;
1142
   case GL_TEXTURE_WRAP_T:
1143
      res = set_sampler_wrap_t(ctx, sampObj, params[0]);
1144
      break;
1145
   case GL_TEXTURE_WRAP_R:
1146
      res = set_sampler_wrap_r(ctx, sampObj, params[0]);
1147
      break;
1148
   case GL_TEXTURE_MIN_FILTER:
1149
      res = set_sampler_min_filter(ctx, sampObj, params[0]);
1150
      break;
1151
   case GL_TEXTURE_MAG_FILTER:
1152
      res = set_sampler_mag_filter(ctx, sampObj, params[0]);
1153
      break;
1154
   case GL_TEXTURE_MIN_LOD:
1155
      res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]);
1156
      break;
1157
   case GL_TEXTURE_MAX_LOD:
1158
      res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]);
1159
      break;
1160
   case GL_TEXTURE_LOD_BIAS:
1161
      res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]);
1162
      break;
1163
   case GL_TEXTURE_COMPARE_MODE:
1164
      res = set_sampler_compare_mode(ctx, sampObj, params[0]);
1165
      break;
1166
   case GL_TEXTURE_COMPARE_FUNC:
1167
      res = set_sampler_compare_func(ctx, sampObj, params[0]);
1168
      break;
1169
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1170
      res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]);
1171
      break;
1172
   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1173
      res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]);
1174
      break;
1175
   case GL_TEXTURE_SRGB_DECODE_EXT:
1176
      res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]);
1177
      break;
1178
   case GL_TEXTURE_BORDER_COLOR:
1179
      res = set_sampler_border_colori(ctx, sampObj, params);
1180
      break;
1181
   default:
1182
      res = INVALID_PNAME;
1183
   }
1184
 
1185
   switch (res) {
1186
   case GL_FALSE:
1187
      /* no change */
1188
      break;
1189
   case GL_TRUE:
1190
      /* state change - we do nothing special at this time */
1191
      break;
1192
   case INVALID_PNAME:
1193
      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(pname=%s)\n",
1194
                  _mesa_lookup_enum_by_nr(pname));
1195
      break;
1196
   case INVALID_PARAM:
1197
      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(param=%d)\n",
1198
                  params[0]);
1199
      break;
1200
   case INVALID_VALUE:
1201
      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(param=%d)\n",
1202
                  params[0]);
1203
      break;
1204
   default:
1205
      ;
1206
   }
1207
}
1208
 
1209
 
1210
void GLAPIENTRY
1211
_mesa_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params)
1212
{
1213
   struct gl_sampler_object *sampObj;
1214
   GLuint res;
1215
   GET_CURRENT_CONTEXT(ctx);
1216
 
1217
   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1218
   if (!sampObj) {
1219
      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(sampler %u)",
1220
                  sampler);
1221
      return;
1222
   }
1223
 
1224
   switch (pname) {
1225
   case GL_TEXTURE_WRAP_S:
1226
      res = set_sampler_wrap_s(ctx, sampObj, params[0]);
1227
      break;
1228
   case GL_TEXTURE_WRAP_T:
1229
      res = set_sampler_wrap_t(ctx, sampObj, params[0]);
1230
      break;
1231
   case GL_TEXTURE_WRAP_R:
1232
      res = set_sampler_wrap_r(ctx, sampObj, params[0]);
1233
      break;
1234
   case GL_TEXTURE_MIN_FILTER:
1235
      res = set_sampler_min_filter(ctx, sampObj, params[0]);
1236
      break;
1237
   case GL_TEXTURE_MAG_FILTER:
1238
      res = set_sampler_mag_filter(ctx, sampObj, params[0]);
1239
      break;
1240
   case GL_TEXTURE_MIN_LOD:
1241
      res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]);
1242
      break;
1243
   case GL_TEXTURE_MAX_LOD:
1244
      res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]);
1245
      break;
1246
   case GL_TEXTURE_LOD_BIAS:
1247
      res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]);
1248
      break;
1249
   case GL_TEXTURE_COMPARE_MODE:
1250
      res = set_sampler_compare_mode(ctx, sampObj, params[0]);
1251
      break;
1252
   case GL_TEXTURE_COMPARE_FUNC:
1253
      res = set_sampler_compare_func(ctx, sampObj, params[0]);
1254
      break;
1255
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1256
      res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]);
1257
      break;
1258
   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1259
      res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]);
1260
      break;
1261
   case GL_TEXTURE_SRGB_DECODE_EXT:
1262
      res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]);
1263
      break;
1264
   case GL_TEXTURE_BORDER_COLOR:
1265
      res = set_sampler_border_colorui(ctx, sampObj, params);
1266
      break;
1267
   default:
1268
      res = INVALID_PNAME;
1269
   }
1270
 
1271
   switch (res) {
1272
   case GL_FALSE:
1273
      /* no change */
1274
      break;
1275
   case GL_TRUE:
1276
      /* state change - we do nothing special at this time */
1277
      break;
1278
   case INVALID_PNAME:
1279
      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(pname=%s)\n",
1280
                  _mesa_lookup_enum_by_nr(pname));
1281
      break;
1282
   case INVALID_PARAM:
1283
      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(param=%u)\n",
1284
                  params[0]);
1285
      break;
1286
   case INVALID_VALUE:
1287
      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(param=%u)\n",
1288
                  params[0]);
1289
      break;
1290
   default:
1291
      ;
1292
   }
1293
}
1294
 
1295
 
1296
void GLAPIENTRY
1297
_mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
1298
{
1299
   struct gl_sampler_object *sampObj;
1300
   GET_CURRENT_CONTEXT(ctx);
1301
 
1302
   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1303
   if (!sampObj) {
1304
      /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states:
1305
       *
1306
       *     "An INVALID_OPERATION error is generated if sampler is not the name
1307
       *     of a sampler object previously returned from a call to GenSamplers."
1308
       *
1309
       * In desktop GL, an GL_INVALID_VALUE is returned instead.
1310
       */
1311
      _mesa_error(ctx, (_mesa_is_gles(ctx) ?
1312
                        GL_INVALID_OPERATION : GL_INVALID_VALUE),
1313
                  "glGetSamplerParameteriv(sampler %u)", sampler);
1314
      return;
1315
   }
1316
 
1317
   switch (pname) {
1318
   case GL_TEXTURE_WRAP_S:
1319
      *params = sampObj->WrapS;
1320
      break;
1321
   case GL_TEXTURE_WRAP_T:
1322
      *params = sampObj->WrapT;
1323
      break;
1324
   case GL_TEXTURE_WRAP_R:
1325
      *params = sampObj->WrapR;
1326
      break;
1327
   case GL_TEXTURE_MIN_FILTER:
1328
      *params = sampObj->MinFilter;
1329
      break;
1330
   case GL_TEXTURE_MAG_FILTER:
1331
      *params = sampObj->MagFilter;
1332
      break;
1333
   case GL_TEXTURE_MIN_LOD:
1334
      /* GL spec 'Data Conversions' section specifies that floating-point
1335
       * value in integer Get function is rounded to nearest integer
1336
       */
1337
      *params = IROUND(sampObj->MinLod);
1338
      break;
1339
   case GL_TEXTURE_MAX_LOD:
1340
      /* GL spec 'Data Conversions' section specifies that floating-point
1341
       * value in integer Get function is rounded to nearest integer
1342
       */
1343
      *params = IROUND(sampObj->MaxLod);
1344
      break;
1345
   case GL_TEXTURE_LOD_BIAS:
1346
      /* GL spec 'Data Conversions' section specifies that floating-point
1347
       * value in integer Get function is rounded to nearest integer
1348
       */
1349
      *params = IROUND(sampObj->LodBias);
1350
      break;
1351
   case GL_TEXTURE_COMPARE_MODE:
1352
      if (!ctx->Extensions.ARB_shadow)
1353
         goto invalid_pname;
1354
      *params = sampObj->CompareMode;
1355
      break;
1356
   case GL_TEXTURE_COMPARE_FUNC:
1357
      if (!ctx->Extensions.ARB_shadow)
1358
         goto invalid_pname;
1359
      *params = sampObj->CompareFunc;
1360
      break;
1361
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1362
      /* GL spec 'Data Conversions' section specifies that floating-point
1363
       * value in integer Get function is rounded to nearest integer
1364
       */
1365
      *params = IROUND(sampObj->MaxAnisotropy);
1366
      break;
1367
   case GL_TEXTURE_BORDER_COLOR:
1368
      params[0] = FLOAT_TO_INT(sampObj->BorderColor.f[0]);
1369
      params[1] = FLOAT_TO_INT(sampObj->BorderColor.f[1]);
1370
      params[2] = FLOAT_TO_INT(sampObj->BorderColor.f[2]);
1371
      params[3] = FLOAT_TO_INT(sampObj->BorderColor.f[3]);
1372
      break;
1373
   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1374
      if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
1375
         goto invalid_pname;
1376
      *params = sampObj->CubeMapSeamless;
1377
      break;
1378
   case GL_TEXTURE_SRGB_DECODE_EXT:
1379
      if (!ctx->Extensions.EXT_texture_sRGB_decode)
1380
         goto invalid_pname;
1381
      *params = (GLenum) sampObj->sRGBDecode;
1382
      break;
1383
   default:
1384
      goto invalid_pname;
1385
   }
1386
   return;
1387
 
1388
invalid_pname:
1389
   _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameteriv(pname=%s)",
1390
               _mesa_lookup_enum_by_nr(pname));
1391
}
1392
 
1393
 
1394
void GLAPIENTRY
1395
_mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
1396
{
1397
   struct gl_sampler_object *sampObj;
1398
   GET_CURRENT_CONTEXT(ctx);
1399
 
1400
   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1401
   if (!sampObj) {
1402
      /* '3.8.2 Sampler Objects' section of the GL-ES 3.0 specification states:
1403
       *
1404
       *     "An INVALID_OPERATION error is generated if sampler is not the name
1405
       *     of a sampler object previously returned from a call to GenSamplers."
1406
       *
1407
       * In desktop GL, an GL_INVALID_VALUE is returned instead.
1408
       */
1409
      _mesa_error(ctx, (_mesa_is_gles(ctx) ?
1410
                        GL_INVALID_OPERATION : GL_INVALID_VALUE),
1411
                  "glGetSamplerParameterfv(sampler %u)", sampler);
1412
      return;
1413
   }
1414
 
1415
   switch (pname) {
1416
   case GL_TEXTURE_WRAP_S:
1417
      *params = (GLfloat) sampObj->WrapS;
1418
      break;
1419
   case GL_TEXTURE_WRAP_T:
1420
      *params = (GLfloat) sampObj->WrapT;
1421
      break;
1422
   case GL_TEXTURE_WRAP_R:
1423
      *params = (GLfloat) sampObj->WrapR;
1424
      break;
1425
   case GL_TEXTURE_MIN_FILTER:
1426
      *params = (GLfloat) sampObj->MinFilter;
1427
      break;
1428
   case GL_TEXTURE_MAG_FILTER:
1429
      *params = (GLfloat) sampObj->MagFilter;
1430
      break;
1431
   case GL_TEXTURE_MIN_LOD:
1432
      *params = sampObj->MinLod;
1433
      break;
1434
   case GL_TEXTURE_MAX_LOD:
1435
      *params = sampObj->MaxLod;
1436
      break;
1437
   case GL_TEXTURE_LOD_BIAS:
1438
      *params = sampObj->LodBias;
1439
      break;
1440
   case GL_TEXTURE_COMPARE_MODE:
1441
      if (!ctx->Extensions.ARB_shadow)
1442
         goto invalid_pname;
1443
      *params = (GLfloat) sampObj->CompareMode;
1444
      break;
1445
   case GL_TEXTURE_COMPARE_FUNC:
1446
      if (!ctx->Extensions.ARB_shadow)
1447
         goto invalid_pname;
1448
      *params = (GLfloat) sampObj->CompareFunc;
1449
      break;
1450
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1451
      *params = sampObj->MaxAnisotropy;
1452
      break;
1453
   case GL_TEXTURE_BORDER_COLOR:
1454
      params[0] = sampObj->BorderColor.f[0];
1455
      params[1] = sampObj->BorderColor.f[1];
1456
      params[2] = sampObj->BorderColor.f[2];
1457
      params[3] = sampObj->BorderColor.f[3];
1458
      break;
1459
   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1460
      if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
1461
         goto invalid_pname;
1462
      *params = (GLfloat) sampObj->CubeMapSeamless;
1463
      break;
1464
   case GL_TEXTURE_SRGB_DECODE_EXT:
1465
      if (!ctx->Extensions.EXT_texture_sRGB_decode)
1466
         goto invalid_pname;
1467
      *params = (GLfloat) sampObj->sRGBDecode;
1468
      break;
1469
   default:
1470
      goto invalid_pname;
1471
   }
1472
   return;
1473
 
1474
invalid_pname:
1475
   _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterfv(pname=%s)",
1476
               _mesa_lookup_enum_by_nr(pname));
1477
}
1478
 
1479
 
1480
void GLAPIENTRY
1481
_mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params)
1482
{
1483
   struct gl_sampler_object *sampObj;
1484
   GET_CURRENT_CONTEXT(ctx);
1485
 
1486
   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1487
   if (!sampObj) {
1488
      _mesa_error(ctx, GL_INVALID_VALUE,
1489
                  "glGetSamplerParameterIiv(sampler %u)",
1490
                  sampler);
1491
      return;
1492
   }
1493
 
1494
   switch (pname) {
1495
   case GL_TEXTURE_WRAP_S:
1496
      *params = sampObj->WrapS;
1497
      break;
1498
   case GL_TEXTURE_WRAP_T:
1499
      *params = sampObj->WrapT;
1500
      break;
1501
   case GL_TEXTURE_WRAP_R:
1502
      *params = sampObj->WrapR;
1503
      break;
1504
   case GL_TEXTURE_MIN_FILTER:
1505
      *params = sampObj->MinFilter;
1506
      break;
1507
   case GL_TEXTURE_MAG_FILTER:
1508
      *params = sampObj->MagFilter;
1509
      break;
1510
   case GL_TEXTURE_MIN_LOD:
1511
      *params = (GLint) sampObj->MinLod;
1512
      break;
1513
   case GL_TEXTURE_MAX_LOD:
1514
      *params = (GLint) sampObj->MaxLod;
1515
      break;
1516
   case GL_TEXTURE_LOD_BIAS:
1517
      *params = (GLint) sampObj->LodBias;
1518
      break;
1519
   case GL_TEXTURE_COMPARE_MODE:
1520
      if (!ctx->Extensions.ARB_shadow)
1521
         goto invalid_pname;
1522
      *params = sampObj->CompareMode;
1523
      break;
1524
   case GL_TEXTURE_COMPARE_FUNC:
1525
      if (!ctx->Extensions.ARB_shadow)
1526
         goto invalid_pname;
1527
      *params = sampObj->CompareFunc;
1528
      break;
1529
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1530
      *params = (GLint) sampObj->MaxAnisotropy;
1531
      break;
1532
   case GL_TEXTURE_BORDER_COLOR:
1533
      params[0] = sampObj->BorderColor.i[0];
1534
      params[1] = sampObj->BorderColor.i[1];
1535
      params[2] = sampObj->BorderColor.i[2];
1536
      params[3] = sampObj->BorderColor.i[3];
1537
      break;
1538
   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1539
      if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
1540
         goto invalid_pname;
1541
      *params = sampObj->CubeMapSeamless;
1542
      break;
1543
   case GL_TEXTURE_SRGB_DECODE_EXT:
1544
      if (!ctx->Extensions.EXT_texture_sRGB_decode)
1545
         goto invalid_pname;
1546
      *params = (GLenum) sampObj->sRGBDecode;
1547
      break;
1548
   default:
1549
      goto invalid_pname;
1550
   }
1551
   return;
1552
 
1553
invalid_pname:
1554
   _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIiv(pname=%s)",
1555
               _mesa_lookup_enum_by_nr(pname));
1556
}
1557
 
1558
 
1559
void GLAPIENTRY
1560
_mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params)
1561
{
1562
   struct gl_sampler_object *sampObj;
1563
   GET_CURRENT_CONTEXT(ctx);
1564
 
1565
   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1566
   if (!sampObj) {
1567
      _mesa_error(ctx, GL_INVALID_VALUE,
1568
                  "glGetSamplerParameterIuiv(sampler %u)",
1569
                  sampler);
1570
      return;
1571
   }
1572
 
1573
   switch (pname) {
1574
   case GL_TEXTURE_WRAP_S:
1575
      *params = sampObj->WrapS;
1576
      break;
1577
   case GL_TEXTURE_WRAP_T:
1578
      *params = sampObj->WrapT;
1579
      break;
1580
   case GL_TEXTURE_WRAP_R:
1581
      *params = sampObj->WrapR;
1582
      break;
1583
   case GL_TEXTURE_MIN_FILTER:
1584
      *params = sampObj->MinFilter;
1585
      break;
1586
   case GL_TEXTURE_MAG_FILTER:
1587
      *params = sampObj->MagFilter;
1588
      break;
1589
   case GL_TEXTURE_MIN_LOD:
1590
      *params = (GLuint) sampObj->MinLod;
1591
      break;
1592
   case GL_TEXTURE_MAX_LOD:
1593
      *params = (GLuint) sampObj->MaxLod;
1594
      break;
1595
   case GL_TEXTURE_LOD_BIAS:
1596
      *params = (GLuint) sampObj->LodBias;
1597
      break;
1598
   case GL_TEXTURE_COMPARE_MODE:
1599
      if (!ctx->Extensions.ARB_shadow)
1600
         goto invalid_pname;
1601
      *params = sampObj->CompareMode;
1602
      break;
1603
   case GL_TEXTURE_COMPARE_FUNC:
1604
      if (!ctx->Extensions.ARB_shadow)
1605
         goto invalid_pname;
1606
      *params = sampObj->CompareFunc;
1607
      break;
1608
   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1609
      *params = (GLuint) sampObj->MaxAnisotropy;
1610
      break;
1611
   case GL_TEXTURE_BORDER_COLOR:
1612
      params[0] = sampObj->BorderColor.ui[0];
1613
      params[1] = sampObj->BorderColor.ui[1];
1614
      params[2] = sampObj->BorderColor.ui[2];
1615
      params[3] = sampObj->BorderColor.ui[3];
1616
      break;
1617
   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1618
      if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
1619
         goto invalid_pname;
1620
      *params = sampObj->CubeMapSeamless;
1621
      break;
1622
   case GL_TEXTURE_SRGB_DECODE_EXT:
1623
      if (!ctx->Extensions.EXT_texture_sRGB_decode)
1624
         goto invalid_pname;
1625
      *params = (GLenum) sampObj->sRGBDecode;
1626
      break;
1627
   default:
1628
      goto invalid_pname;
1629
   }
1630
   return;
1631
 
1632
invalid_pname:
1633
   _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIuiv(pname=%s)",
1634
               _mesa_lookup_enum_by_nr(pname));
1635
}
1636
 
1637
 
1638
void
1639
_mesa_init_sampler_object_functions(struct dd_function_table *driver)
1640
{
1641
   driver->NewSamplerObject = _mesa_new_sampler_object;
1642
   driver->DeleteSamplerObject = _mesa_delete_sampler_object;
1643
}