~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/mesa/main/samplerobj.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

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