samplerobj.c revision 848b8605
1848b8605Smrg/*
2848b8605Smrg * Mesa 3-D graphics library
3848b8605Smrg *
4848b8605Smrg * Copyright (C) 2011  VMware, Inc.  All Rights Reserved.
5848b8605Smrg *
6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
7848b8605Smrg * copy of this software and associated documentation files (the "Software"),
8848b8605Smrg * to deal in the Software without restriction, including without limitation
9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
11848b8605Smrg * Software is furnished to do so, subject to the following conditions:
12848b8605Smrg *
13848b8605Smrg * The above copyright notice and this permission notice shall be included
14848b8605Smrg * in all copies or substantial portions of the Software.
15848b8605Smrg *
16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE.
23848b8605Smrg */
24848b8605Smrg
25848b8605Smrg
26848b8605Smrg/**
27848b8605Smrg * \file samplerobj.c
28848b8605Smrg * \brief Functions for the GL_ARB_sampler_objects extension.
29848b8605Smrg * \author Brian Paul
30848b8605Smrg */
31848b8605Smrg
32848b8605Smrg
33848b8605Smrg#include "main/glheader.h"
34848b8605Smrg#include "main/context.h"
35848b8605Smrg#include "main/dispatch.h"
36848b8605Smrg#include "main/enums.h"
37848b8605Smrg#include "main/hash.h"
38848b8605Smrg#include "main/macros.h"
39848b8605Smrg#include "main/mtypes.h"
40848b8605Smrg#include "main/samplerobj.h"
41848b8605Smrg
42848b8605Smrg
43848b8605Smrgstruct gl_sampler_object *
44848b8605Smrg_mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name)
45848b8605Smrg{
46848b8605Smrg   if (name == 0)
47848b8605Smrg      return NULL;
48848b8605Smrg   else
49848b8605Smrg      return (struct gl_sampler_object *)
50848b8605Smrg         _mesa_HashLookup(ctx->Shared->SamplerObjects, name);
51848b8605Smrg}
52848b8605Smrg
53848b8605Smrg
54848b8605Smrgstatic inline void
55848b8605Smrgbegin_samplerobj_lookups(struct gl_context *ctx)
56848b8605Smrg{
57848b8605Smrg   _mesa_HashLockMutex(ctx->Shared->SamplerObjects);
58848b8605Smrg}
59848b8605Smrg
60848b8605Smrg
61848b8605Smrgstatic inline void
62848b8605Smrgend_samplerobj_lookups(struct gl_context *ctx)
63848b8605Smrg{
64848b8605Smrg   _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects);
65848b8605Smrg}
66848b8605Smrg
67848b8605Smrg
68848b8605Smrgstatic inline struct gl_sampler_object *
69848b8605Smrglookup_samplerobj_locked(struct gl_context *ctx, GLuint name)
70848b8605Smrg{
71848b8605Smrg   return (struct gl_sampler_object *)
72848b8605Smrg         _mesa_HashLookupLocked(ctx->Shared->SamplerObjects, name);
73848b8605Smrg}
74848b8605Smrg
75848b8605Smrg
76848b8605Smrg/**
77848b8605Smrg * Handle reference counting.
78848b8605Smrg */
79848b8605Smrgvoid
80848b8605Smrg_mesa_reference_sampler_object_(struct gl_context *ctx,
81848b8605Smrg                                struct gl_sampler_object **ptr,
82848b8605Smrg                                struct gl_sampler_object *samp)
83848b8605Smrg{
84848b8605Smrg   assert(*ptr != samp); /* The inline wrapper should prevent no-op calls */
85848b8605Smrg
86848b8605Smrg   if (*ptr) {
87848b8605Smrg      /* Unreference the old sampler */
88848b8605Smrg      GLboolean deleteFlag = GL_FALSE;
89848b8605Smrg      struct gl_sampler_object *oldSamp = *ptr;
90848b8605Smrg
91848b8605Smrg      /*mtx_lock(&oldSamp->Mutex);*/
92848b8605Smrg      ASSERT(oldSamp->RefCount > 0);
93848b8605Smrg      oldSamp->RefCount--;
94848b8605Smrg#if 0
95848b8605Smrg      printf("SamplerObj %p %d DECR to %d\n",
96848b8605Smrg             (void *) oldSamp, oldSamp->Name, oldSamp->RefCount);
97848b8605Smrg#endif
98848b8605Smrg      deleteFlag = (oldSamp->RefCount == 0);
99848b8605Smrg      /*mtx_unlock(&oldSamp->Mutex);*/
100848b8605Smrg
101848b8605Smrg      if (deleteFlag) {
102848b8605Smrg	 ASSERT(ctx->Driver.DeleteSamplerObject);
103848b8605Smrg         ctx->Driver.DeleteSamplerObject(ctx, oldSamp);
104848b8605Smrg      }
105848b8605Smrg
106848b8605Smrg      *ptr = NULL;
107848b8605Smrg   }
108848b8605Smrg   ASSERT(!*ptr);
109848b8605Smrg
110848b8605Smrg   if (samp) {
111848b8605Smrg      /* reference new sampler */
112848b8605Smrg      /*mtx_lock(&samp->Mutex);*/
113848b8605Smrg      if (samp->RefCount == 0) {
114848b8605Smrg         /* this sampler's being deleted (look just above) */
115848b8605Smrg         /* Not sure this can every really happen.  Warn if it does. */
116848b8605Smrg         _mesa_problem(NULL, "referencing deleted sampler object");
117848b8605Smrg         *ptr = NULL;
118848b8605Smrg      }
119848b8605Smrg      else {
120848b8605Smrg         samp->RefCount++;
121848b8605Smrg#if 0
122848b8605Smrg         printf("SamplerObj %p %d INCR to %d\n",
123848b8605Smrg                (void *) samp, samp->Name, samp->RefCount);
124848b8605Smrg#endif
125848b8605Smrg         *ptr = samp;
126848b8605Smrg      }
127848b8605Smrg      /*mtx_unlock(&samp->Mutex);*/
128848b8605Smrg   }
129848b8605Smrg}
130848b8605Smrg
131848b8605Smrg
132848b8605Smrg/**
133848b8605Smrg * Initialize the fields of the given sampler object.
134848b8605Smrg */
135848b8605Smrgstatic void
136848b8605Smrg_mesa_init_sampler_object(struct gl_sampler_object *sampObj, GLuint name)
137848b8605Smrg{
138848b8605Smrg   sampObj->Name = name;
139848b8605Smrg   sampObj->RefCount = 1;
140848b8605Smrg   sampObj->WrapS = GL_REPEAT;
141848b8605Smrg   sampObj->WrapT = GL_REPEAT;
142848b8605Smrg   sampObj->WrapR = GL_REPEAT;
143848b8605Smrg   sampObj->MinFilter = GL_NEAREST_MIPMAP_LINEAR;
144848b8605Smrg   sampObj->MagFilter = GL_LINEAR;
145848b8605Smrg   sampObj->BorderColor.f[0] = 0.0;
146848b8605Smrg   sampObj->BorderColor.f[1] = 0.0;
147848b8605Smrg   sampObj->BorderColor.f[2] = 0.0;
148848b8605Smrg   sampObj->BorderColor.f[3] = 0.0;
149848b8605Smrg   sampObj->MinLod = -1000.0F;
150848b8605Smrg   sampObj->MaxLod = 1000.0F;
151848b8605Smrg   sampObj->LodBias = 0.0F;
152848b8605Smrg   sampObj->MaxAnisotropy = 1.0F;
153848b8605Smrg   sampObj->CompareMode = GL_NONE;
154848b8605Smrg   sampObj->CompareFunc = GL_LEQUAL;
155848b8605Smrg   sampObj->sRGBDecode = GL_DECODE_EXT;
156848b8605Smrg   sampObj->CubeMapSeamless = GL_FALSE;
157848b8605Smrg}
158848b8605Smrg
159848b8605Smrg/**
160848b8605Smrg * Fallback for ctx->Driver.NewSamplerObject();
161848b8605Smrg */
162848b8605Smrgstruct gl_sampler_object *
163848b8605Smrg_mesa_new_sampler_object(struct gl_context *ctx, GLuint name)
164848b8605Smrg{
165848b8605Smrg   struct gl_sampler_object *sampObj = CALLOC_STRUCT(gl_sampler_object);
166848b8605Smrg   if (sampObj) {
167848b8605Smrg      _mesa_init_sampler_object(sampObj, name);
168848b8605Smrg   }
169848b8605Smrg   return sampObj;
170848b8605Smrg}
171848b8605Smrg
172848b8605Smrg
173848b8605Smrg/**
174848b8605Smrg * Fallback for ctx->Driver.DeleteSamplerObject();
175848b8605Smrg */
176848b8605Smrgstatic void
177848b8605Smrg_mesa_delete_sampler_object(struct gl_context *ctx,
178848b8605Smrg                            struct gl_sampler_object *sampObj)
179848b8605Smrg{
180848b8605Smrg   free(sampObj->Label);
181848b8605Smrg   free(sampObj);
182848b8605Smrg}
183848b8605Smrg
184848b8605Smrg
185848b8605Smrgvoid GLAPIENTRY
186848b8605Smrg_mesa_GenSamplers(GLsizei count, GLuint *samplers)
187848b8605Smrg{
188848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
189848b8605Smrg   GLuint first;
190848b8605Smrg   GLint i;
191848b8605Smrg
192848b8605Smrg   if (MESA_VERBOSE & VERBOSE_API)
193848b8605Smrg      _mesa_debug(ctx, "glGenSamplers(%d)\n", count);
194848b8605Smrg
195848b8605Smrg   if (count < 0) {
196848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glGenSamplers");
197848b8605Smrg      return;
198848b8605Smrg   }
199848b8605Smrg
200848b8605Smrg   if (!samplers)
201848b8605Smrg      return;
202848b8605Smrg
203848b8605Smrg   first = _mesa_HashFindFreeKeyBlock(ctx->Shared->SamplerObjects, count);
204848b8605Smrg
205848b8605Smrg   /* Insert the ID and pointer to new sampler object into hash table */
206848b8605Smrg   for (i = 0; i < count; i++) {
207848b8605Smrg      struct gl_sampler_object *sampObj =
208848b8605Smrg         ctx->Driver.NewSamplerObject(ctx, first + i);
209848b8605Smrg      _mesa_HashInsert(ctx->Shared->SamplerObjects, first + i, sampObj);
210848b8605Smrg      samplers[i] = first + i;
211848b8605Smrg   }
212848b8605Smrg}
213848b8605Smrg
214848b8605Smrg
215848b8605Smrgvoid GLAPIENTRY
216848b8605Smrg_mesa_DeleteSamplers(GLsizei count, const GLuint *samplers)
217848b8605Smrg{
218848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
219848b8605Smrg   GLsizei i;
220848b8605Smrg
221848b8605Smrg   FLUSH_VERTICES(ctx, 0);
222848b8605Smrg
223848b8605Smrg   if (count < 0) {
224848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteSamplers(count)");
225848b8605Smrg      return;
226848b8605Smrg   }
227848b8605Smrg
228848b8605Smrg   mtx_lock(&ctx->Shared->Mutex);
229848b8605Smrg
230848b8605Smrg   for (i = 0; i < count; i++) {
231848b8605Smrg      if (samplers[i]) {
232848b8605Smrg         GLuint j;
233848b8605Smrg         struct gl_sampler_object *sampObj =
234848b8605Smrg            _mesa_lookup_samplerobj(ctx, samplers[i]);
235848b8605Smrg
236848b8605Smrg         if (sampObj) {
237848b8605Smrg            /* If the sampler is currently bound, unbind it. */
238848b8605Smrg            for (j = 0; j < ctx->Const.MaxCombinedTextureImageUnits; j++) {
239848b8605Smrg               if (ctx->Texture.Unit[j].Sampler == sampObj) {
240848b8605Smrg                  FLUSH_VERTICES(ctx, _NEW_TEXTURE);
241848b8605Smrg                  _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[j].Sampler, NULL);
242848b8605Smrg               }
243848b8605Smrg            }
244848b8605Smrg
245848b8605Smrg            /* The ID is immediately freed for re-use */
246848b8605Smrg            _mesa_HashRemove(ctx->Shared->SamplerObjects, samplers[i]);
247848b8605Smrg            /* But the object exists until its reference count goes to zero */
248848b8605Smrg            _mesa_reference_sampler_object(ctx, &sampObj, NULL);
249848b8605Smrg         }
250848b8605Smrg      }
251848b8605Smrg   }
252848b8605Smrg
253848b8605Smrg   mtx_unlock(&ctx->Shared->Mutex);
254848b8605Smrg}
255848b8605Smrg
256848b8605Smrg
257848b8605SmrgGLboolean GLAPIENTRY
258848b8605Smrg_mesa_IsSampler(GLuint sampler)
259848b8605Smrg{
260848b8605Smrg   struct gl_sampler_object *sampObj;
261848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
262848b8605Smrg
263848b8605Smrg   ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
264848b8605Smrg
265848b8605Smrg   if (sampler == 0)
266848b8605Smrg      return GL_FALSE;
267848b8605Smrg
268848b8605Smrg   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
269848b8605Smrg
270848b8605Smrg   return sampObj != NULL;
271848b8605Smrg}
272848b8605Smrg
273848b8605Smrg
274848b8605Smrgvoid GLAPIENTRY
275848b8605Smrg_mesa_BindSampler(GLuint unit, GLuint sampler)
276848b8605Smrg{
277848b8605Smrg   struct gl_sampler_object *sampObj;
278848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
279848b8605Smrg
280848b8605Smrg   if (unit >= ctx->Const.MaxCombinedTextureImageUnits) {
281848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glBindSampler(unit %u)", unit);
282848b8605Smrg      return;
283848b8605Smrg   }
284848b8605Smrg
285848b8605Smrg   if (sampler == 0) {
286848b8605Smrg      /* Use the default sampler object, the one contained in the texture
287848b8605Smrg       * object.
288848b8605Smrg       */
289848b8605Smrg      sampObj = NULL;
290848b8605Smrg   }
291848b8605Smrg   else {
292848b8605Smrg      /* user-defined sampler object */
293848b8605Smrg      sampObj = _mesa_lookup_samplerobj(ctx, sampler);
294848b8605Smrg      if (!sampObj) {
295848b8605Smrg         _mesa_error(ctx, GL_INVALID_OPERATION, "glBindSampler(sampler)");
296848b8605Smrg         return;
297848b8605Smrg      }
298848b8605Smrg   }
299848b8605Smrg
300848b8605Smrg   if (ctx->Texture.Unit[unit].Sampler != sampObj) {
301848b8605Smrg      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
302848b8605Smrg   }
303848b8605Smrg
304848b8605Smrg   /* bind new sampler */
305848b8605Smrg   _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[unit].Sampler,
306848b8605Smrg                                  sampObj);
307848b8605Smrg}
308848b8605Smrg
309848b8605Smrg
310848b8605Smrgvoid GLAPIENTRY
311848b8605Smrg_mesa_BindSamplers(GLuint first, GLsizei count, const GLuint *samplers)
312848b8605Smrg{
313848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
314848b8605Smrg   GLint i;
315848b8605Smrg
316848b8605Smrg   /* The ARB_multi_bind spec says:
317848b8605Smrg    *
318848b8605Smrg    *   "An INVALID_OPERATION error is generated if <first> + <count> is
319848b8605Smrg    *    greater than the number of texture image units supported by
320848b8605Smrg    *    the implementation."
321848b8605Smrg    */
322848b8605Smrg   if (first + count > ctx->Const.MaxCombinedTextureImageUnits) {
323848b8605Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
324848b8605Smrg                  "glBindSamplers(first=%u + count=%d > the value of "
325848b8605Smrg                  "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS=%u)",
326848b8605Smrg                  first, count, ctx->Const.MaxCombinedTextureImageUnits);
327848b8605Smrg      return;
328848b8605Smrg   }
329848b8605Smrg
330848b8605Smrg   FLUSH_VERTICES(ctx, 0);
331848b8605Smrg
332848b8605Smrg   if (samplers) {
333848b8605Smrg      /* Note that the error semantics for multi-bind commands differ from
334848b8605Smrg       * those of other GL commands.
335848b8605Smrg       *
336848b8605Smrg       * The Issues section in the ARB_multi_bind spec says:
337848b8605Smrg       *
338848b8605Smrg       *    "(11) Typically, OpenGL specifies that if an error is generated by
339848b8605Smrg       *          a command, that command has no effect.  This is somewhat
340848b8605Smrg       *          unfortunate for multi-bind commands, because it would require
341848b8605Smrg       *          a first pass to scan the entire list of bound objects for
342848b8605Smrg       *          errors and then a second pass to actually perform the
343848b8605Smrg       *          bindings.  Should we have different error semantics?
344848b8605Smrg       *
345848b8605Smrg       *       RESOLVED:  Yes.  In this specification, when the parameters for
346848b8605Smrg       *       one of the <count> binding points are invalid, that binding
347848b8605Smrg       *       point is not updated and an error will be generated.  However,
348848b8605Smrg       *       other binding points in the same command will be updated if
349848b8605Smrg       *       their parameters are valid and no other error occurs."
350848b8605Smrg       */
351848b8605Smrg
352848b8605Smrg      begin_samplerobj_lookups(ctx);
353848b8605Smrg
354848b8605Smrg      for (i = 0; i < count; i++) {
355848b8605Smrg         const GLuint unit = first + i;
356848b8605Smrg         struct gl_sampler_object * const currentSampler =
357848b8605Smrg             ctx->Texture.Unit[unit].Sampler;
358848b8605Smrg         struct gl_sampler_object *sampObj;
359848b8605Smrg
360848b8605Smrg         if (samplers[i] != 0) {
361848b8605Smrg            if (currentSampler && currentSampler->Name == samplers[i])
362848b8605Smrg               sampObj = currentSampler;
363848b8605Smrg            else
364848b8605Smrg               sampObj = lookup_samplerobj_locked(ctx, samplers[i]);
365848b8605Smrg
366848b8605Smrg            /* The ARB_multi_bind spec says:
367848b8605Smrg             *
368848b8605Smrg             *    "An INVALID_OPERATION error is generated if any value
369848b8605Smrg             *     in <samplers> is not zero or the name of an existing
370848b8605Smrg             *     sampler object (per binding)."
371848b8605Smrg             */
372848b8605Smrg            if (!sampObj) {
373848b8605Smrg               _mesa_error(ctx, GL_INVALID_OPERATION,
374848b8605Smrg                           "glBindSamplers(samplers[%d]=%u is not zero or "
375848b8605Smrg                           "the name of an existing sampler object)",
376848b8605Smrg                           i, samplers[i]);
377848b8605Smrg               continue;
378848b8605Smrg            }
379848b8605Smrg         } else {
380848b8605Smrg            sampObj = NULL;
381848b8605Smrg         }
382848b8605Smrg
383848b8605Smrg         /* Bind the new sampler */
384848b8605Smrg         if (sampObj != currentSampler) {
385848b8605Smrg            _mesa_reference_sampler_object(ctx,
386848b8605Smrg                                           &ctx->Texture.Unit[unit].Sampler,
387848b8605Smrg                                           sampObj);
388848b8605Smrg            ctx->NewState |= _NEW_TEXTURE;
389848b8605Smrg         }
390848b8605Smrg      }
391848b8605Smrg
392848b8605Smrg      end_samplerobj_lookups(ctx);
393848b8605Smrg   } else {
394848b8605Smrg      /* Unbind all samplers in the range <first> through <first>+<count>-1 */
395848b8605Smrg      for (i = 0; i < count; i++) {
396848b8605Smrg         const GLuint unit = first + i;
397848b8605Smrg
398848b8605Smrg         if (ctx->Texture.Unit[unit].Sampler) {
399848b8605Smrg            _mesa_reference_sampler_object(ctx,
400848b8605Smrg                                           &ctx->Texture.Unit[unit].Sampler,
401848b8605Smrg                                           NULL);
402848b8605Smrg            ctx->NewState |= _NEW_TEXTURE;
403848b8605Smrg         }
404848b8605Smrg      }
405848b8605Smrg   }
406848b8605Smrg}
407848b8605Smrg
408848b8605Smrg
409848b8605Smrg/**
410848b8605Smrg * Check if a coordinate wrap mode is legal.
411848b8605Smrg * \return GL_TRUE if legal, GL_FALSE otherwise
412848b8605Smrg */
413848b8605Smrgstatic GLboolean
414848b8605Smrgvalidate_texture_wrap_mode(struct gl_context *ctx, GLenum wrap)
415848b8605Smrg{
416848b8605Smrg   const struct gl_extensions * const e = &ctx->Extensions;
417848b8605Smrg
418848b8605Smrg   switch (wrap) {
419848b8605Smrg   case GL_CLAMP:
420848b8605Smrg   case GL_CLAMP_TO_EDGE:
421848b8605Smrg   case GL_REPEAT:
422848b8605Smrg   case GL_MIRRORED_REPEAT:
423848b8605Smrg      return GL_TRUE;
424848b8605Smrg   case GL_CLAMP_TO_BORDER:
425848b8605Smrg      return e->ARB_texture_border_clamp;
426848b8605Smrg   case GL_MIRROR_CLAMP_EXT:
427848b8605Smrg      return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp;
428848b8605Smrg   case GL_MIRROR_CLAMP_TO_EDGE_EXT:
429848b8605Smrg      return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp || e->ARB_texture_mirror_clamp_to_edge;
430848b8605Smrg   case GL_MIRROR_CLAMP_TO_BORDER_EXT:
431848b8605Smrg      return e->EXT_texture_mirror_clamp;
432848b8605Smrg   default:
433848b8605Smrg      return GL_FALSE;
434848b8605Smrg   }
435848b8605Smrg}
436848b8605Smrg
437848b8605Smrg
438848b8605Smrg/**
439848b8605Smrg * This is called just prior to changing any sampler object state.
440848b8605Smrg */
441848b8605Smrgstatic inline void
442848b8605Smrgflush(struct gl_context *ctx)
443848b8605Smrg{
444848b8605Smrg   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
445848b8605Smrg}
446848b8605Smrg
447848b8605Smrg
448848b8605Smrg#define INVALID_PARAM 0x100
449848b8605Smrg#define INVALID_PNAME 0x101
450848b8605Smrg#define INVALID_VALUE 0x102
451848b8605Smrg
452848b8605Smrgstatic GLuint
453848b8605Smrgset_sampler_wrap_s(struct gl_context *ctx, struct gl_sampler_object *samp,
454848b8605Smrg                   GLint param)
455848b8605Smrg{
456848b8605Smrg   if (samp->WrapS == param)
457848b8605Smrg      return GL_FALSE;
458848b8605Smrg   if (validate_texture_wrap_mode(ctx, param)) {
459848b8605Smrg      flush(ctx);
460848b8605Smrg      samp->WrapS = param;
461848b8605Smrg      return GL_TRUE;
462848b8605Smrg   }
463848b8605Smrg   return INVALID_PARAM;
464848b8605Smrg}
465848b8605Smrg
466848b8605Smrg
467848b8605Smrgstatic GLuint
468848b8605Smrgset_sampler_wrap_t(struct gl_context *ctx, struct gl_sampler_object *samp,
469848b8605Smrg                   GLint param)
470848b8605Smrg{
471848b8605Smrg   if (samp->WrapT == param)
472848b8605Smrg      return GL_FALSE;
473848b8605Smrg   if (validate_texture_wrap_mode(ctx, param)) {
474848b8605Smrg      flush(ctx);
475848b8605Smrg      samp->WrapT = param;
476848b8605Smrg      return GL_TRUE;
477848b8605Smrg   }
478848b8605Smrg   return INVALID_PARAM;
479848b8605Smrg}
480848b8605Smrg
481848b8605Smrg
482848b8605Smrgstatic GLuint
483848b8605Smrgset_sampler_wrap_r(struct gl_context *ctx, struct gl_sampler_object *samp,
484848b8605Smrg                   GLint param)
485848b8605Smrg{
486848b8605Smrg   if (samp->WrapR == param)
487848b8605Smrg      return GL_FALSE;
488848b8605Smrg   if (validate_texture_wrap_mode(ctx, param)) {
489848b8605Smrg      flush(ctx);
490848b8605Smrg      samp->WrapR = param;
491848b8605Smrg      return GL_TRUE;
492848b8605Smrg   }
493848b8605Smrg   return INVALID_PARAM;
494848b8605Smrg}
495848b8605Smrg
496848b8605Smrg
497848b8605Smrgstatic GLuint
498848b8605Smrgset_sampler_min_filter(struct gl_context *ctx, struct gl_sampler_object *samp,
499848b8605Smrg                       GLint param)
500848b8605Smrg{
501848b8605Smrg   if (samp->MinFilter == param)
502848b8605Smrg      return GL_FALSE;
503848b8605Smrg
504848b8605Smrg   switch (param) {
505848b8605Smrg   case GL_NEAREST:
506848b8605Smrg   case GL_LINEAR:
507848b8605Smrg   case GL_NEAREST_MIPMAP_NEAREST:
508848b8605Smrg   case GL_LINEAR_MIPMAP_NEAREST:
509848b8605Smrg   case GL_NEAREST_MIPMAP_LINEAR:
510848b8605Smrg   case GL_LINEAR_MIPMAP_LINEAR:
511848b8605Smrg      flush(ctx);
512848b8605Smrg      samp->MinFilter = param;
513848b8605Smrg      return GL_TRUE;
514848b8605Smrg   default:
515848b8605Smrg      return INVALID_PARAM;
516848b8605Smrg   }
517848b8605Smrg}
518848b8605Smrg
519848b8605Smrg
520848b8605Smrgstatic GLuint
521848b8605Smrgset_sampler_mag_filter(struct gl_context *ctx, struct gl_sampler_object *samp,
522848b8605Smrg                       GLint param)
523848b8605Smrg{
524848b8605Smrg   if (samp->MagFilter == param)
525848b8605Smrg      return GL_FALSE;
526848b8605Smrg
527848b8605Smrg   switch (param) {
528848b8605Smrg   case GL_NEAREST:
529848b8605Smrg   case GL_LINEAR:
530848b8605Smrg      flush(ctx);
531848b8605Smrg      samp->MagFilter = param;
532848b8605Smrg      return GL_TRUE;
533848b8605Smrg   default:
534848b8605Smrg      return INVALID_PARAM;
535848b8605Smrg   }
536848b8605Smrg}
537848b8605Smrg
538848b8605Smrg
539848b8605Smrgstatic GLuint
540848b8605Smrgset_sampler_lod_bias(struct gl_context *ctx, struct gl_sampler_object *samp,
541848b8605Smrg                     GLfloat param)
542848b8605Smrg{
543848b8605Smrg   if (samp->LodBias == param)
544848b8605Smrg      return GL_FALSE;
545848b8605Smrg
546848b8605Smrg   flush(ctx);
547848b8605Smrg   samp->LodBias = param;
548848b8605Smrg   return GL_TRUE;
549848b8605Smrg}
550848b8605Smrg
551848b8605Smrg
552848b8605Smrgstatic GLuint
553848b8605Smrgset_sampler_border_colorf(struct gl_context *ctx,
554848b8605Smrg                          struct gl_sampler_object *samp,
555848b8605Smrg                          const GLfloat params[4])
556848b8605Smrg{
557848b8605Smrg   flush(ctx);
558848b8605Smrg   samp->BorderColor.f[RCOMP] = params[0];
559848b8605Smrg   samp->BorderColor.f[GCOMP] = params[1];
560848b8605Smrg   samp->BorderColor.f[BCOMP] = params[2];
561848b8605Smrg   samp->BorderColor.f[ACOMP] = params[3];
562848b8605Smrg   return GL_TRUE;
563848b8605Smrg}
564848b8605Smrg
565848b8605Smrg
566848b8605Smrgstatic GLuint
567848b8605Smrgset_sampler_border_colori(struct gl_context *ctx,
568848b8605Smrg                          struct gl_sampler_object *samp,
569848b8605Smrg                          const GLint params[4])
570848b8605Smrg{
571848b8605Smrg   flush(ctx);
572848b8605Smrg   samp->BorderColor.i[RCOMP] = params[0];
573848b8605Smrg   samp->BorderColor.i[GCOMP] = params[1];
574848b8605Smrg   samp->BorderColor.i[BCOMP] = params[2];
575848b8605Smrg   samp->BorderColor.i[ACOMP] = params[3];
576848b8605Smrg   return GL_TRUE;
577848b8605Smrg}
578848b8605Smrg
579848b8605Smrg
580848b8605Smrgstatic GLuint
581848b8605Smrgset_sampler_border_colorui(struct gl_context *ctx,
582848b8605Smrg                           struct gl_sampler_object *samp,
583848b8605Smrg                           const GLuint params[4])
584848b8605Smrg{
585848b8605Smrg   flush(ctx);
586848b8605Smrg   samp->BorderColor.ui[RCOMP] = params[0];
587848b8605Smrg   samp->BorderColor.ui[GCOMP] = params[1];
588848b8605Smrg   samp->BorderColor.ui[BCOMP] = params[2];
589848b8605Smrg   samp->BorderColor.ui[ACOMP] = params[3];
590848b8605Smrg   return GL_TRUE;
591848b8605Smrg}
592848b8605Smrg
593848b8605Smrg
594848b8605Smrgstatic GLuint
595848b8605Smrgset_sampler_min_lod(struct gl_context *ctx, struct gl_sampler_object *samp,
596848b8605Smrg                    GLfloat param)
597848b8605Smrg{
598848b8605Smrg   if (samp->MinLod == param)
599848b8605Smrg      return GL_FALSE;
600848b8605Smrg
601848b8605Smrg   flush(ctx);
602848b8605Smrg   samp->MinLod = param;
603848b8605Smrg   return GL_TRUE;
604848b8605Smrg}
605848b8605Smrg
606848b8605Smrg
607848b8605Smrgstatic GLuint
608848b8605Smrgset_sampler_max_lod(struct gl_context *ctx, struct gl_sampler_object *samp,
609848b8605Smrg                    GLfloat param)
610848b8605Smrg{
611848b8605Smrg   if (samp->MaxLod == param)
612848b8605Smrg      return GL_FALSE;
613848b8605Smrg
614848b8605Smrg   flush(ctx);
615848b8605Smrg   samp->MaxLod = param;
616848b8605Smrg   return GL_TRUE;
617848b8605Smrg}
618848b8605Smrg
619848b8605Smrg
620848b8605Smrgstatic GLuint
621848b8605Smrgset_sampler_compare_mode(struct gl_context *ctx,
622848b8605Smrg                         struct gl_sampler_object *samp, GLint param)
623848b8605Smrg{
624848b8605Smrg   if (!ctx->Extensions.ARB_shadow)
625848b8605Smrg      return INVALID_PNAME;
626848b8605Smrg
627848b8605Smrg   if (samp->CompareMode == param)
628848b8605Smrg      return GL_FALSE;
629848b8605Smrg
630848b8605Smrg   if (param == GL_NONE ||
631848b8605Smrg       param == GL_COMPARE_R_TO_TEXTURE_ARB) {
632848b8605Smrg      flush(ctx);
633848b8605Smrg      samp->CompareMode = param;
634848b8605Smrg      return GL_TRUE;
635848b8605Smrg   }
636848b8605Smrg
637848b8605Smrg   return INVALID_PARAM;
638848b8605Smrg}
639848b8605Smrg
640848b8605Smrg
641848b8605Smrgstatic GLuint
642848b8605Smrgset_sampler_compare_func(struct gl_context *ctx,
643848b8605Smrg                         struct gl_sampler_object *samp, GLint param)
644848b8605Smrg{
645848b8605Smrg   if (!ctx->Extensions.ARB_shadow)
646848b8605Smrg      return INVALID_PNAME;
647848b8605Smrg
648848b8605Smrg   if (samp->CompareFunc == param)
649848b8605Smrg      return GL_FALSE;
650848b8605Smrg
651848b8605Smrg   switch (param) {
652848b8605Smrg   case GL_LEQUAL:
653848b8605Smrg   case GL_GEQUAL:
654848b8605Smrg   case GL_EQUAL:
655848b8605Smrg   case GL_NOTEQUAL:
656848b8605Smrg   case GL_LESS:
657848b8605Smrg   case GL_GREATER:
658848b8605Smrg   case GL_ALWAYS:
659848b8605Smrg   case GL_NEVER:
660848b8605Smrg      flush(ctx);
661848b8605Smrg      samp->CompareFunc = param;
662848b8605Smrg      return GL_TRUE;
663848b8605Smrg   default:
664848b8605Smrg      return INVALID_PARAM;
665848b8605Smrg   }
666848b8605Smrg}
667848b8605Smrg
668848b8605Smrg
669848b8605Smrgstatic GLuint
670848b8605Smrgset_sampler_max_anisotropy(struct gl_context *ctx,
671848b8605Smrg                           struct gl_sampler_object *samp, GLfloat param)
672848b8605Smrg{
673848b8605Smrg   if (!ctx->Extensions.EXT_texture_filter_anisotropic)
674848b8605Smrg      return INVALID_PNAME;
675848b8605Smrg
676848b8605Smrg   if (samp->MaxAnisotropy == param)
677848b8605Smrg      return GL_FALSE;
678848b8605Smrg
679848b8605Smrg   if (param < 1.0)
680848b8605Smrg      return INVALID_VALUE;
681848b8605Smrg
682848b8605Smrg   flush(ctx);
683848b8605Smrg   /* clamp to max, that's what NVIDIA does */
684848b8605Smrg   samp->MaxAnisotropy = MIN2(param, ctx->Const.MaxTextureMaxAnisotropy);
685848b8605Smrg   return GL_TRUE;
686848b8605Smrg}
687848b8605Smrg
688848b8605Smrg
689848b8605Smrgstatic GLuint
690848b8605Smrgset_sampler_cube_map_seamless(struct gl_context *ctx,
691848b8605Smrg                              struct gl_sampler_object *samp, GLboolean param)
692848b8605Smrg{
693848b8605Smrg   if (!_mesa_is_desktop_gl(ctx)
694848b8605Smrg       || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
695848b8605Smrg      return INVALID_PNAME;
696848b8605Smrg
697848b8605Smrg   if (samp->CubeMapSeamless == param)
698848b8605Smrg      return GL_FALSE;
699848b8605Smrg
700848b8605Smrg   if (param != GL_TRUE && param != GL_FALSE)
701848b8605Smrg      return INVALID_VALUE;
702848b8605Smrg
703848b8605Smrg   flush(ctx);
704848b8605Smrg   samp->CubeMapSeamless = param;
705848b8605Smrg   return GL_TRUE;
706848b8605Smrg}
707848b8605Smrg
708848b8605Smrgstatic GLuint
709848b8605Smrgset_sampler_srgb_decode(struct gl_context *ctx,
710848b8605Smrg                              struct gl_sampler_object *samp, GLenum param)
711848b8605Smrg{
712848b8605Smrg   if (!ctx->Extensions.EXT_texture_sRGB_decode)
713848b8605Smrg      return INVALID_PNAME;
714848b8605Smrg
715848b8605Smrg   if (samp->sRGBDecode == param)
716848b8605Smrg      return GL_FALSE;
717848b8605Smrg
718848b8605Smrg   if (param != GL_DECODE_EXT && param != GL_SKIP_DECODE_EXT)
719848b8605Smrg      return INVALID_VALUE;
720848b8605Smrg
721848b8605Smrg   flush(ctx);
722848b8605Smrg   samp->sRGBDecode = param;
723848b8605Smrg   return GL_TRUE;
724848b8605Smrg}
725848b8605Smrg
726848b8605Smrgvoid GLAPIENTRY
727848b8605Smrg_mesa_SamplerParameteri(GLuint sampler, GLenum pname, GLint param)
728848b8605Smrg{
729848b8605Smrg   struct gl_sampler_object *sampObj;
730848b8605Smrg   GLuint res;
731848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
732848b8605Smrg
733848b8605Smrg   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
734848b8605Smrg   if (!sampObj) {
735848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteri(sampler %u)",
736848b8605Smrg                  sampler);
737848b8605Smrg      return;
738848b8605Smrg   }
739848b8605Smrg
740848b8605Smrg   switch (pname) {
741848b8605Smrg   case GL_TEXTURE_WRAP_S:
742848b8605Smrg      res = set_sampler_wrap_s(ctx, sampObj, param);
743848b8605Smrg      break;
744848b8605Smrg   case GL_TEXTURE_WRAP_T:
745848b8605Smrg      res = set_sampler_wrap_t(ctx, sampObj, param);
746848b8605Smrg      break;
747848b8605Smrg   case GL_TEXTURE_WRAP_R:
748848b8605Smrg      res = set_sampler_wrap_r(ctx, sampObj, param);
749848b8605Smrg      break;
750848b8605Smrg   case GL_TEXTURE_MIN_FILTER:
751848b8605Smrg      res = set_sampler_min_filter(ctx, sampObj, param);
752848b8605Smrg      break;
753848b8605Smrg   case GL_TEXTURE_MAG_FILTER:
754848b8605Smrg      res = set_sampler_mag_filter(ctx, sampObj, param);
755848b8605Smrg      break;
756848b8605Smrg   case GL_TEXTURE_MIN_LOD:
757848b8605Smrg      res = set_sampler_min_lod(ctx, sampObj, (GLfloat) param);
758848b8605Smrg      break;
759848b8605Smrg   case GL_TEXTURE_MAX_LOD:
760848b8605Smrg      res = set_sampler_max_lod(ctx, sampObj, (GLfloat) param);
761848b8605Smrg      break;
762848b8605Smrg   case GL_TEXTURE_LOD_BIAS:
763848b8605Smrg      res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) param);
764848b8605Smrg      break;
765848b8605Smrg   case GL_TEXTURE_COMPARE_MODE:
766848b8605Smrg      res = set_sampler_compare_mode(ctx, sampObj, param);
767848b8605Smrg      break;
768848b8605Smrg   case GL_TEXTURE_COMPARE_FUNC:
769848b8605Smrg      res = set_sampler_compare_func(ctx, sampObj, param);
770848b8605Smrg      break;
771848b8605Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
772848b8605Smrg      res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) param);
773848b8605Smrg      break;
774848b8605Smrg   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
775848b8605Smrg      res = set_sampler_cube_map_seamless(ctx, sampObj, param);
776848b8605Smrg      break;
777848b8605Smrg   case GL_TEXTURE_SRGB_DECODE_EXT:
778848b8605Smrg      res = set_sampler_srgb_decode(ctx, sampObj, param);
779848b8605Smrg      break;
780848b8605Smrg   case GL_TEXTURE_BORDER_COLOR:
781848b8605Smrg      /* fall-through */
782848b8605Smrg   default:
783848b8605Smrg      res = INVALID_PNAME;
784848b8605Smrg   }
785848b8605Smrg
786848b8605Smrg   switch (res) {
787848b8605Smrg   case GL_FALSE:
788848b8605Smrg      /* no change */
789848b8605Smrg      break;
790848b8605Smrg   case GL_TRUE:
791848b8605Smrg      /* state change - we do nothing special at this time */
792848b8605Smrg      break;
793848b8605Smrg   case INVALID_PNAME:
794848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(pname=%s)\n",
795848b8605Smrg                  _mesa_lookup_enum_by_nr(pname));
796848b8605Smrg      break;
797848b8605Smrg   case INVALID_PARAM:
798848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteri(param=%d)\n",
799848b8605Smrg                  param);
800848b8605Smrg      break;
801848b8605Smrg   case INVALID_VALUE:
802848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteri(param=%d)\n",
803848b8605Smrg                  param);
804848b8605Smrg      break;
805848b8605Smrg   default:
806848b8605Smrg      ;
807848b8605Smrg   }
808848b8605Smrg}
809848b8605Smrg
810848b8605Smrg
811848b8605Smrgvoid GLAPIENTRY
812848b8605Smrg_mesa_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
813848b8605Smrg{
814848b8605Smrg   struct gl_sampler_object *sampObj;
815848b8605Smrg   GLuint res;
816848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
817848b8605Smrg
818848b8605Smrg   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
819848b8605Smrg   if (!sampObj) {
820848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterf(sampler %u)",
821848b8605Smrg                  sampler);
822848b8605Smrg      return;
823848b8605Smrg   }
824848b8605Smrg
825848b8605Smrg   switch (pname) {
826848b8605Smrg   case GL_TEXTURE_WRAP_S:
827848b8605Smrg      res = set_sampler_wrap_s(ctx, sampObj, (GLint) param);
828848b8605Smrg      break;
829848b8605Smrg   case GL_TEXTURE_WRAP_T:
830848b8605Smrg      res = set_sampler_wrap_t(ctx, sampObj, (GLint) param);
831848b8605Smrg      break;
832848b8605Smrg   case GL_TEXTURE_WRAP_R:
833848b8605Smrg      res = set_sampler_wrap_r(ctx, sampObj, (GLint) param);
834848b8605Smrg      break;
835848b8605Smrg   case GL_TEXTURE_MIN_FILTER:
836848b8605Smrg      res = set_sampler_min_filter(ctx, sampObj, (GLint) param);
837848b8605Smrg      break;
838848b8605Smrg   case GL_TEXTURE_MAG_FILTER:
839848b8605Smrg      res = set_sampler_mag_filter(ctx, sampObj, (GLint) param);
840848b8605Smrg      break;
841848b8605Smrg   case GL_TEXTURE_MIN_LOD:
842848b8605Smrg      res = set_sampler_min_lod(ctx, sampObj, param);
843848b8605Smrg      break;
844848b8605Smrg   case GL_TEXTURE_MAX_LOD:
845848b8605Smrg      res = set_sampler_max_lod(ctx, sampObj, param);
846848b8605Smrg      break;
847848b8605Smrg   case GL_TEXTURE_LOD_BIAS:
848848b8605Smrg      res = set_sampler_lod_bias(ctx, sampObj, param);
849848b8605Smrg      break;
850848b8605Smrg   case GL_TEXTURE_COMPARE_MODE:
851848b8605Smrg      res = set_sampler_compare_mode(ctx, sampObj, (GLint) param);
852848b8605Smrg      break;
853848b8605Smrg   case GL_TEXTURE_COMPARE_FUNC:
854848b8605Smrg      res = set_sampler_compare_func(ctx, sampObj, (GLint) param);
855848b8605Smrg      break;
856848b8605Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
857848b8605Smrg      res = set_sampler_max_anisotropy(ctx, sampObj, param);
858848b8605Smrg      break;
859848b8605Smrg   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
860848b8605Smrg      res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) param);
861848b8605Smrg      break;
862848b8605Smrg   case GL_TEXTURE_SRGB_DECODE_EXT:
863848b8605Smrg      res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) param);
864848b8605Smrg      break;
865848b8605Smrg   case GL_TEXTURE_BORDER_COLOR:
866848b8605Smrg      /* fall-through */
867848b8605Smrg   default:
868848b8605Smrg      res = INVALID_PNAME;
869848b8605Smrg   }
870848b8605Smrg
871848b8605Smrg   switch (res) {
872848b8605Smrg   case GL_FALSE:
873848b8605Smrg      /* no change */
874848b8605Smrg      break;
875848b8605Smrg   case GL_TRUE:
876848b8605Smrg      /* state change - we do nothing special at this time */
877848b8605Smrg      break;
878848b8605Smrg   case INVALID_PNAME:
879848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(pname=%s)\n",
880848b8605Smrg                  _mesa_lookup_enum_by_nr(pname));
881848b8605Smrg      break;
882848b8605Smrg   case INVALID_PARAM:
883848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterf(param=%f)\n",
884848b8605Smrg                  param);
885848b8605Smrg      break;
886848b8605Smrg   case INVALID_VALUE:
887848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterf(param=%f)\n",
888848b8605Smrg                  param);
889848b8605Smrg      break;
890848b8605Smrg   default:
891848b8605Smrg      ;
892848b8605Smrg   }
893848b8605Smrg}
894848b8605Smrg
895848b8605Smrgvoid GLAPIENTRY
896848b8605Smrg_mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params)
897848b8605Smrg{
898848b8605Smrg   struct gl_sampler_object *sampObj;
899848b8605Smrg   GLuint res;
900848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
901848b8605Smrg
902848b8605Smrg   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
903848b8605Smrg   if (!sampObj) {
904848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteriv(sampler %u)",
905848b8605Smrg                  sampler);
906848b8605Smrg      return;
907848b8605Smrg   }
908848b8605Smrg
909848b8605Smrg   switch (pname) {
910848b8605Smrg   case GL_TEXTURE_WRAP_S:
911848b8605Smrg      res = set_sampler_wrap_s(ctx, sampObj, params[0]);
912848b8605Smrg      break;
913848b8605Smrg   case GL_TEXTURE_WRAP_T:
914848b8605Smrg      res = set_sampler_wrap_t(ctx, sampObj, params[0]);
915848b8605Smrg      break;
916848b8605Smrg   case GL_TEXTURE_WRAP_R:
917848b8605Smrg      res = set_sampler_wrap_r(ctx, sampObj, params[0]);
918848b8605Smrg      break;
919848b8605Smrg   case GL_TEXTURE_MIN_FILTER:
920848b8605Smrg      res = set_sampler_min_filter(ctx, sampObj, params[0]);
921848b8605Smrg      break;
922848b8605Smrg   case GL_TEXTURE_MAG_FILTER:
923848b8605Smrg      res = set_sampler_mag_filter(ctx, sampObj, params[0]);
924848b8605Smrg      break;
925848b8605Smrg   case GL_TEXTURE_MIN_LOD:
926848b8605Smrg      res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]);
927848b8605Smrg      break;
928848b8605Smrg   case GL_TEXTURE_MAX_LOD:
929848b8605Smrg      res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]);
930848b8605Smrg      break;
931848b8605Smrg   case GL_TEXTURE_LOD_BIAS:
932848b8605Smrg      res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]);
933848b8605Smrg      break;
934848b8605Smrg   case GL_TEXTURE_COMPARE_MODE:
935848b8605Smrg      res = set_sampler_compare_mode(ctx, sampObj, params[0]);
936848b8605Smrg      break;
937848b8605Smrg   case GL_TEXTURE_COMPARE_FUNC:
938848b8605Smrg      res = set_sampler_compare_func(ctx, sampObj, params[0]);
939848b8605Smrg      break;
940848b8605Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
941848b8605Smrg      res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]);
942848b8605Smrg      break;
943848b8605Smrg   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
944848b8605Smrg      res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]);
945848b8605Smrg      break;
946848b8605Smrg   case GL_TEXTURE_SRGB_DECODE_EXT:
947848b8605Smrg      res = set_sampler_srgb_decode(ctx, sampObj, params[0]);
948848b8605Smrg      break;
949848b8605Smrg   case GL_TEXTURE_BORDER_COLOR:
950848b8605Smrg      {
951848b8605Smrg         GLfloat c[4];
952848b8605Smrg         c[0] = INT_TO_FLOAT(params[0]);
953848b8605Smrg         c[1] = INT_TO_FLOAT(params[1]);
954848b8605Smrg         c[2] = INT_TO_FLOAT(params[2]);
955848b8605Smrg         c[3] = INT_TO_FLOAT(params[3]);
956848b8605Smrg         res = set_sampler_border_colorf(ctx, sampObj, c);
957848b8605Smrg      }
958848b8605Smrg      break;
959848b8605Smrg   default:
960848b8605Smrg      res = INVALID_PNAME;
961848b8605Smrg   }
962848b8605Smrg
963848b8605Smrg   switch (res) {
964848b8605Smrg   case GL_FALSE:
965848b8605Smrg      /* no change */
966848b8605Smrg      break;
967848b8605Smrg   case GL_TRUE:
968848b8605Smrg      /* state change - we do nothing special at this time */
969848b8605Smrg      break;
970848b8605Smrg   case INVALID_PNAME:
971848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(pname=%s)\n",
972848b8605Smrg                  _mesa_lookup_enum_by_nr(pname));
973848b8605Smrg      break;
974848b8605Smrg   case INVALID_PARAM:
975848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameteriv(param=%d)\n",
976848b8605Smrg                  params[0]);
977848b8605Smrg      break;
978848b8605Smrg   case INVALID_VALUE:
979848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameteriv(param=%d)\n",
980848b8605Smrg                  params[0]);
981848b8605Smrg      break;
982848b8605Smrg   default:
983848b8605Smrg      ;
984848b8605Smrg   }
985848b8605Smrg}
986848b8605Smrg
987848b8605Smrgvoid GLAPIENTRY
988848b8605Smrg_mesa_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params)
989848b8605Smrg{
990848b8605Smrg   struct gl_sampler_object *sampObj;
991848b8605Smrg   GLuint res;
992848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
993848b8605Smrg
994848b8605Smrg   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
995848b8605Smrg   if (!sampObj) {
996848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterfv(sampler %u)",
997848b8605Smrg                  sampler);
998848b8605Smrg      return;
999848b8605Smrg   }
1000848b8605Smrg
1001848b8605Smrg   switch (pname) {
1002848b8605Smrg   case GL_TEXTURE_WRAP_S:
1003848b8605Smrg      res = set_sampler_wrap_s(ctx, sampObj, (GLint) params[0]);
1004848b8605Smrg      break;
1005848b8605Smrg   case GL_TEXTURE_WRAP_T:
1006848b8605Smrg      res = set_sampler_wrap_t(ctx, sampObj, (GLint) params[0]);
1007848b8605Smrg      break;
1008848b8605Smrg   case GL_TEXTURE_WRAP_R:
1009848b8605Smrg      res = set_sampler_wrap_r(ctx, sampObj, (GLint) params[0]);
1010848b8605Smrg      break;
1011848b8605Smrg   case GL_TEXTURE_MIN_FILTER:
1012848b8605Smrg      res = set_sampler_min_filter(ctx, sampObj, (GLint) params[0]);
1013848b8605Smrg      break;
1014848b8605Smrg   case GL_TEXTURE_MAG_FILTER:
1015848b8605Smrg      res = set_sampler_mag_filter(ctx, sampObj, (GLint) params[0]);
1016848b8605Smrg      break;
1017848b8605Smrg   case GL_TEXTURE_MIN_LOD:
1018848b8605Smrg      res = set_sampler_min_lod(ctx, sampObj, params[0]);
1019848b8605Smrg      break;
1020848b8605Smrg   case GL_TEXTURE_MAX_LOD:
1021848b8605Smrg      res = set_sampler_max_lod(ctx, sampObj, params[0]);
1022848b8605Smrg      break;
1023848b8605Smrg   case GL_TEXTURE_LOD_BIAS:
1024848b8605Smrg      res = set_sampler_lod_bias(ctx, sampObj, params[0]);
1025848b8605Smrg      break;
1026848b8605Smrg   case GL_TEXTURE_COMPARE_MODE:
1027848b8605Smrg      res = set_sampler_compare_mode(ctx, sampObj, (GLint) params[0]);
1028848b8605Smrg      break;
1029848b8605Smrg   case GL_TEXTURE_COMPARE_FUNC:
1030848b8605Smrg      res = set_sampler_compare_func(ctx, sampObj, (GLint) params[0]);
1031848b8605Smrg      break;
1032848b8605Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1033848b8605Smrg      res = set_sampler_max_anisotropy(ctx, sampObj, params[0]);
1034848b8605Smrg      break;
1035848b8605Smrg   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1036848b8605Smrg      res = set_sampler_cube_map_seamless(ctx, sampObj, (GLboolean) params[0]);
1037848b8605Smrg      break;
1038848b8605Smrg   case GL_TEXTURE_SRGB_DECODE_EXT:
1039848b8605Smrg      res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]);
1040848b8605Smrg      break;
1041848b8605Smrg   case GL_TEXTURE_BORDER_COLOR:
1042848b8605Smrg      res = set_sampler_border_colorf(ctx, sampObj, params);
1043848b8605Smrg      break;
1044848b8605Smrg   default:
1045848b8605Smrg      res = INVALID_PNAME;
1046848b8605Smrg   }
1047848b8605Smrg
1048848b8605Smrg   switch (res) {
1049848b8605Smrg   case GL_FALSE:
1050848b8605Smrg      /* no change */
1051848b8605Smrg      break;
1052848b8605Smrg   case GL_TRUE:
1053848b8605Smrg      /* state change - we do nothing special at this time */
1054848b8605Smrg      break;
1055848b8605Smrg   case INVALID_PNAME:
1056848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(pname=%s)\n",
1057848b8605Smrg                  _mesa_lookup_enum_by_nr(pname));
1058848b8605Smrg      break;
1059848b8605Smrg   case INVALID_PARAM:
1060848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterfv(param=%f)\n",
1061848b8605Smrg                  params[0]);
1062848b8605Smrg      break;
1063848b8605Smrg   case INVALID_VALUE:
1064848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterfv(param=%f)\n",
1065848b8605Smrg                  params[0]);
1066848b8605Smrg      break;
1067848b8605Smrg   default:
1068848b8605Smrg      ;
1069848b8605Smrg   }
1070848b8605Smrg}
1071848b8605Smrg
1072848b8605Smrgvoid GLAPIENTRY
1073848b8605Smrg_mesa_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params)
1074848b8605Smrg{
1075848b8605Smrg   struct gl_sampler_object *sampObj;
1076848b8605Smrg   GLuint res;
1077848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1078848b8605Smrg
1079848b8605Smrg   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1080848b8605Smrg   if (!sampObj) {
1081848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(sampler %u)",
1082848b8605Smrg                  sampler);
1083848b8605Smrg      return;
1084848b8605Smrg   }
1085848b8605Smrg
1086848b8605Smrg   switch (pname) {
1087848b8605Smrg   case GL_TEXTURE_WRAP_S:
1088848b8605Smrg      res = set_sampler_wrap_s(ctx, sampObj, params[0]);
1089848b8605Smrg      break;
1090848b8605Smrg   case GL_TEXTURE_WRAP_T:
1091848b8605Smrg      res = set_sampler_wrap_t(ctx, sampObj, params[0]);
1092848b8605Smrg      break;
1093848b8605Smrg   case GL_TEXTURE_WRAP_R:
1094848b8605Smrg      res = set_sampler_wrap_r(ctx, sampObj, params[0]);
1095848b8605Smrg      break;
1096848b8605Smrg   case GL_TEXTURE_MIN_FILTER:
1097848b8605Smrg      res = set_sampler_min_filter(ctx, sampObj, params[0]);
1098848b8605Smrg      break;
1099848b8605Smrg   case GL_TEXTURE_MAG_FILTER:
1100848b8605Smrg      res = set_sampler_mag_filter(ctx, sampObj, params[0]);
1101848b8605Smrg      break;
1102848b8605Smrg   case GL_TEXTURE_MIN_LOD:
1103848b8605Smrg      res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]);
1104848b8605Smrg      break;
1105848b8605Smrg   case GL_TEXTURE_MAX_LOD:
1106848b8605Smrg      res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]);
1107848b8605Smrg      break;
1108848b8605Smrg   case GL_TEXTURE_LOD_BIAS:
1109848b8605Smrg      res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]);
1110848b8605Smrg      break;
1111848b8605Smrg   case GL_TEXTURE_COMPARE_MODE:
1112848b8605Smrg      res = set_sampler_compare_mode(ctx, sampObj, params[0]);
1113848b8605Smrg      break;
1114848b8605Smrg   case GL_TEXTURE_COMPARE_FUNC:
1115848b8605Smrg      res = set_sampler_compare_func(ctx, sampObj, params[0]);
1116848b8605Smrg      break;
1117848b8605Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1118848b8605Smrg      res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]);
1119848b8605Smrg      break;
1120848b8605Smrg   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1121848b8605Smrg      res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]);
1122848b8605Smrg      break;
1123848b8605Smrg   case GL_TEXTURE_SRGB_DECODE_EXT:
1124848b8605Smrg      res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]);
1125848b8605Smrg      break;
1126848b8605Smrg   case GL_TEXTURE_BORDER_COLOR:
1127848b8605Smrg      res = set_sampler_border_colori(ctx, sampObj, params);
1128848b8605Smrg      break;
1129848b8605Smrg   default:
1130848b8605Smrg      res = INVALID_PNAME;
1131848b8605Smrg   }
1132848b8605Smrg
1133848b8605Smrg   switch (res) {
1134848b8605Smrg   case GL_FALSE:
1135848b8605Smrg      /* no change */
1136848b8605Smrg      break;
1137848b8605Smrg   case GL_TRUE:
1138848b8605Smrg      /* state change - we do nothing special at this time */
1139848b8605Smrg      break;
1140848b8605Smrg   case INVALID_PNAME:
1141848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(pname=%s)\n",
1142848b8605Smrg                  _mesa_lookup_enum_by_nr(pname));
1143848b8605Smrg      break;
1144848b8605Smrg   case INVALID_PARAM:
1145848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIiv(param=%d)\n",
1146848b8605Smrg                  params[0]);
1147848b8605Smrg      break;
1148848b8605Smrg   case INVALID_VALUE:
1149848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIiv(param=%d)\n",
1150848b8605Smrg                  params[0]);
1151848b8605Smrg      break;
1152848b8605Smrg   default:
1153848b8605Smrg      ;
1154848b8605Smrg   }
1155848b8605Smrg}
1156848b8605Smrg
1157848b8605Smrg
1158848b8605Smrgvoid GLAPIENTRY
1159848b8605Smrg_mesa_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params)
1160848b8605Smrg{
1161848b8605Smrg   struct gl_sampler_object *sampObj;
1162848b8605Smrg   GLuint res;
1163848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1164848b8605Smrg
1165848b8605Smrg   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1166848b8605Smrg   if (!sampObj) {
1167848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(sampler %u)",
1168848b8605Smrg                  sampler);
1169848b8605Smrg      return;
1170848b8605Smrg   }
1171848b8605Smrg
1172848b8605Smrg   switch (pname) {
1173848b8605Smrg   case GL_TEXTURE_WRAP_S:
1174848b8605Smrg      res = set_sampler_wrap_s(ctx, sampObj, params[0]);
1175848b8605Smrg      break;
1176848b8605Smrg   case GL_TEXTURE_WRAP_T:
1177848b8605Smrg      res = set_sampler_wrap_t(ctx, sampObj, params[0]);
1178848b8605Smrg      break;
1179848b8605Smrg   case GL_TEXTURE_WRAP_R:
1180848b8605Smrg      res = set_sampler_wrap_r(ctx, sampObj, params[0]);
1181848b8605Smrg      break;
1182848b8605Smrg   case GL_TEXTURE_MIN_FILTER:
1183848b8605Smrg      res = set_sampler_min_filter(ctx, sampObj, params[0]);
1184848b8605Smrg      break;
1185848b8605Smrg   case GL_TEXTURE_MAG_FILTER:
1186848b8605Smrg      res = set_sampler_mag_filter(ctx, sampObj, params[0]);
1187848b8605Smrg      break;
1188848b8605Smrg   case GL_TEXTURE_MIN_LOD:
1189848b8605Smrg      res = set_sampler_min_lod(ctx, sampObj, (GLfloat) params[0]);
1190848b8605Smrg      break;
1191848b8605Smrg   case GL_TEXTURE_MAX_LOD:
1192848b8605Smrg      res = set_sampler_max_lod(ctx, sampObj, (GLfloat) params[0]);
1193848b8605Smrg      break;
1194848b8605Smrg   case GL_TEXTURE_LOD_BIAS:
1195848b8605Smrg      res = set_sampler_lod_bias(ctx, sampObj, (GLfloat) params[0]);
1196848b8605Smrg      break;
1197848b8605Smrg   case GL_TEXTURE_COMPARE_MODE:
1198848b8605Smrg      res = set_sampler_compare_mode(ctx, sampObj, params[0]);
1199848b8605Smrg      break;
1200848b8605Smrg   case GL_TEXTURE_COMPARE_FUNC:
1201848b8605Smrg      res = set_sampler_compare_func(ctx, sampObj, params[0]);
1202848b8605Smrg      break;
1203848b8605Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1204848b8605Smrg      res = set_sampler_max_anisotropy(ctx, sampObj, (GLfloat) params[0]);
1205848b8605Smrg      break;
1206848b8605Smrg   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1207848b8605Smrg      res = set_sampler_cube_map_seamless(ctx, sampObj, params[0]);
1208848b8605Smrg      break;
1209848b8605Smrg   case GL_TEXTURE_SRGB_DECODE_EXT:
1210848b8605Smrg      res = set_sampler_srgb_decode(ctx, sampObj, (GLenum) params[0]);
1211848b8605Smrg      break;
1212848b8605Smrg   case GL_TEXTURE_BORDER_COLOR:
1213848b8605Smrg      res = set_sampler_border_colorui(ctx, sampObj, params);
1214848b8605Smrg      break;
1215848b8605Smrg   default:
1216848b8605Smrg      res = INVALID_PNAME;
1217848b8605Smrg   }
1218848b8605Smrg
1219848b8605Smrg   switch (res) {
1220848b8605Smrg   case GL_FALSE:
1221848b8605Smrg      /* no change */
1222848b8605Smrg      break;
1223848b8605Smrg   case GL_TRUE:
1224848b8605Smrg      /* state change - we do nothing special at this time */
1225848b8605Smrg      break;
1226848b8605Smrg   case INVALID_PNAME:
1227848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(pname=%s)\n",
1228848b8605Smrg                  _mesa_lookup_enum_by_nr(pname));
1229848b8605Smrg      break;
1230848b8605Smrg   case INVALID_PARAM:
1231848b8605Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glSamplerParameterIuiv(param=%u)\n",
1232848b8605Smrg                  params[0]);
1233848b8605Smrg      break;
1234848b8605Smrg   case INVALID_VALUE:
1235848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glSamplerParameterIuiv(param=%u)\n",
1236848b8605Smrg                  params[0]);
1237848b8605Smrg      break;
1238848b8605Smrg   default:
1239848b8605Smrg      ;
1240848b8605Smrg   }
1241848b8605Smrg}
1242848b8605Smrg
1243848b8605Smrg
1244848b8605Smrgvoid GLAPIENTRY
1245848b8605Smrg_mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params)
1246848b8605Smrg{
1247848b8605Smrg   struct gl_sampler_object *sampObj;
1248848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1249848b8605Smrg
1250848b8605Smrg   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1251848b8605Smrg   if (!sampObj) {
1252848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glGetSamplerParameteriv(sampler %u)",
1253848b8605Smrg                  sampler);
1254848b8605Smrg      return;
1255848b8605Smrg   }
1256848b8605Smrg
1257848b8605Smrg   switch (pname) {
1258848b8605Smrg   case GL_TEXTURE_WRAP_S:
1259848b8605Smrg      *params = sampObj->WrapS;
1260848b8605Smrg      break;
1261848b8605Smrg   case GL_TEXTURE_WRAP_T:
1262848b8605Smrg      *params = sampObj->WrapT;
1263848b8605Smrg      break;
1264848b8605Smrg   case GL_TEXTURE_WRAP_R:
1265848b8605Smrg      *params = sampObj->WrapR;
1266848b8605Smrg      break;
1267848b8605Smrg   case GL_TEXTURE_MIN_FILTER:
1268848b8605Smrg      *params = sampObj->MinFilter;
1269848b8605Smrg      break;
1270848b8605Smrg   case GL_TEXTURE_MAG_FILTER:
1271848b8605Smrg      *params = sampObj->MagFilter;
1272848b8605Smrg      break;
1273848b8605Smrg   case GL_TEXTURE_MIN_LOD:
1274848b8605Smrg      *params = (GLint) sampObj->MinLod;
1275848b8605Smrg      break;
1276848b8605Smrg   case GL_TEXTURE_MAX_LOD:
1277848b8605Smrg      *params = (GLint) sampObj->MaxLod;
1278848b8605Smrg      break;
1279848b8605Smrg   case GL_TEXTURE_LOD_BIAS:
1280848b8605Smrg      *params = (GLint) sampObj->LodBias;
1281848b8605Smrg      break;
1282848b8605Smrg   case GL_TEXTURE_COMPARE_MODE:
1283848b8605Smrg      if (!ctx->Extensions.ARB_shadow)
1284848b8605Smrg         goto invalid_pname;
1285848b8605Smrg      *params = sampObj->CompareMode;
1286848b8605Smrg      break;
1287848b8605Smrg   case GL_TEXTURE_COMPARE_FUNC:
1288848b8605Smrg      if (!ctx->Extensions.ARB_shadow)
1289848b8605Smrg         goto invalid_pname;
1290848b8605Smrg      *params = sampObj->CompareFunc;
1291848b8605Smrg      break;
1292848b8605Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1293848b8605Smrg      *params = (GLint) sampObj->MaxAnisotropy;
1294848b8605Smrg      break;
1295848b8605Smrg   case GL_TEXTURE_BORDER_COLOR:
1296848b8605Smrg      params[0] = FLOAT_TO_INT(sampObj->BorderColor.f[0]);
1297848b8605Smrg      params[1] = FLOAT_TO_INT(sampObj->BorderColor.f[1]);
1298848b8605Smrg      params[2] = FLOAT_TO_INT(sampObj->BorderColor.f[2]);
1299848b8605Smrg      params[3] = FLOAT_TO_INT(sampObj->BorderColor.f[3]);
1300848b8605Smrg      break;
1301848b8605Smrg   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1302848b8605Smrg      if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
1303848b8605Smrg         goto invalid_pname;
1304848b8605Smrg      *params = sampObj->CubeMapSeamless;
1305848b8605Smrg      break;
1306848b8605Smrg   case GL_TEXTURE_SRGB_DECODE_EXT:
1307848b8605Smrg      if (!ctx->Extensions.EXT_texture_sRGB_decode)
1308848b8605Smrg         goto invalid_pname;
1309848b8605Smrg      *params = (GLenum) sampObj->sRGBDecode;
1310848b8605Smrg      break;
1311848b8605Smrg   default:
1312848b8605Smrg      goto invalid_pname;
1313848b8605Smrg   }
1314848b8605Smrg   return;
1315848b8605Smrg
1316848b8605Smrginvalid_pname:
1317848b8605Smrg   _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameteriv(pname=%s)",
1318848b8605Smrg               _mesa_lookup_enum_by_nr(pname));
1319848b8605Smrg}
1320848b8605Smrg
1321848b8605Smrg
1322848b8605Smrgvoid GLAPIENTRY
1323848b8605Smrg_mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params)
1324848b8605Smrg{
1325848b8605Smrg   struct gl_sampler_object *sampObj;
1326848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1327848b8605Smrg
1328848b8605Smrg   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1329848b8605Smrg   if (!sampObj) {
1330848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE, "glGetSamplerParameterfv(sampler %u)",
1331848b8605Smrg                  sampler);
1332848b8605Smrg      return;
1333848b8605Smrg   }
1334848b8605Smrg
1335848b8605Smrg   switch (pname) {
1336848b8605Smrg   case GL_TEXTURE_WRAP_S:
1337848b8605Smrg      *params = (GLfloat) sampObj->WrapS;
1338848b8605Smrg      break;
1339848b8605Smrg   case GL_TEXTURE_WRAP_T:
1340848b8605Smrg      *params = (GLfloat) sampObj->WrapT;
1341848b8605Smrg      break;
1342848b8605Smrg   case GL_TEXTURE_WRAP_R:
1343848b8605Smrg      *params = (GLfloat) sampObj->WrapR;
1344848b8605Smrg      break;
1345848b8605Smrg   case GL_TEXTURE_MIN_FILTER:
1346848b8605Smrg      *params = (GLfloat) sampObj->MinFilter;
1347848b8605Smrg      break;
1348848b8605Smrg   case GL_TEXTURE_MAG_FILTER:
1349848b8605Smrg      *params = (GLfloat) sampObj->MagFilter;
1350848b8605Smrg      break;
1351848b8605Smrg   case GL_TEXTURE_MIN_LOD:
1352848b8605Smrg      *params = sampObj->MinLod;
1353848b8605Smrg      break;
1354848b8605Smrg   case GL_TEXTURE_MAX_LOD:
1355848b8605Smrg      *params = sampObj->MaxLod;
1356848b8605Smrg      break;
1357848b8605Smrg   case GL_TEXTURE_LOD_BIAS:
1358848b8605Smrg      *params = sampObj->LodBias;
1359848b8605Smrg      break;
1360848b8605Smrg   case GL_TEXTURE_COMPARE_MODE:
1361848b8605Smrg      if (!ctx->Extensions.ARB_shadow)
1362848b8605Smrg         goto invalid_pname;
1363848b8605Smrg      *params = (GLfloat) sampObj->CompareMode;
1364848b8605Smrg      break;
1365848b8605Smrg   case GL_TEXTURE_COMPARE_FUNC:
1366848b8605Smrg      if (!ctx->Extensions.ARB_shadow)
1367848b8605Smrg         goto invalid_pname;
1368848b8605Smrg      *params = (GLfloat) sampObj->CompareFunc;
1369848b8605Smrg      break;
1370848b8605Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1371848b8605Smrg      *params = sampObj->MaxAnisotropy;
1372848b8605Smrg      break;
1373848b8605Smrg   case GL_TEXTURE_BORDER_COLOR:
1374848b8605Smrg      params[0] = sampObj->BorderColor.f[0];
1375848b8605Smrg      params[1] = sampObj->BorderColor.f[1];
1376848b8605Smrg      params[2] = sampObj->BorderColor.f[2];
1377848b8605Smrg      params[3] = sampObj->BorderColor.f[3];
1378848b8605Smrg      break;
1379848b8605Smrg   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1380848b8605Smrg      if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
1381848b8605Smrg         goto invalid_pname;
1382848b8605Smrg      *params = (GLfloat) sampObj->CubeMapSeamless;
1383848b8605Smrg      break;
1384848b8605Smrg   case GL_TEXTURE_SRGB_DECODE_EXT:
1385848b8605Smrg      if (!ctx->Extensions.EXT_texture_sRGB_decode)
1386848b8605Smrg         goto invalid_pname;
1387848b8605Smrg      *params = (GLfloat) sampObj->sRGBDecode;
1388848b8605Smrg      break;
1389848b8605Smrg   default:
1390848b8605Smrg      goto invalid_pname;
1391848b8605Smrg   }
1392848b8605Smrg   return;
1393848b8605Smrg
1394848b8605Smrginvalid_pname:
1395848b8605Smrg   _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterfv(pname=%s)",
1396848b8605Smrg               _mesa_lookup_enum_by_nr(pname));
1397848b8605Smrg}
1398848b8605Smrg
1399848b8605Smrg
1400848b8605Smrgvoid GLAPIENTRY
1401848b8605Smrg_mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params)
1402848b8605Smrg{
1403848b8605Smrg   struct gl_sampler_object *sampObj;
1404848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1405848b8605Smrg
1406848b8605Smrg   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1407848b8605Smrg   if (!sampObj) {
1408848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE,
1409848b8605Smrg                  "glGetSamplerParameterIiv(sampler %u)",
1410848b8605Smrg                  sampler);
1411848b8605Smrg      return;
1412848b8605Smrg   }
1413848b8605Smrg
1414848b8605Smrg   switch (pname) {
1415848b8605Smrg   case GL_TEXTURE_WRAP_S:
1416848b8605Smrg      *params = sampObj->WrapS;
1417848b8605Smrg      break;
1418848b8605Smrg   case GL_TEXTURE_WRAP_T:
1419848b8605Smrg      *params = sampObj->WrapT;
1420848b8605Smrg      break;
1421848b8605Smrg   case GL_TEXTURE_WRAP_R:
1422848b8605Smrg      *params = sampObj->WrapR;
1423848b8605Smrg      break;
1424848b8605Smrg   case GL_TEXTURE_MIN_FILTER:
1425848b8605Smrg      *params = sampObj->MinFilter;
1426848b8605Smrg      break;
1427848b8605Smrg   case GL_TEXTURE_MAG_FILTER:
1428848b8605Smrg      *params = sampObj->MagFilter;
1429848b8605Smrg      break;
1430848b8605Smrg   case GL_TEXTURE_MIN_LOD:
1431848b8605Smrg      *params = (GLint) sampObj->MinLod;
1432848b8605Smrg      break;
1433848b8605Smrg   case GL_TEXTURE_MAX_LOD:
1434848b8605Smrg      *params = (GLint) sampObj->MaxLod;
1435848b8605Smrg      break;
1436848b8605Smrg   case GL_TEXTURE_LOD_BIAS:
1437848b8605Smrg      *params = (GLint) sampObj->LodBias;
1438848b8605Smrg      break;
1439848b8605Smrg   case GL_TEXTURE_COMPARE_MODE:
1440848b8605Smrg      if (!ctx->Extensions.ARB_shadow)
1441848b8605Smrg         goto invalid_pname;
1442848b8605Smrg      *params = sampObj->CompareMode;
1443848b8605Smrg      break;
1444848b8605Smrg   case GL_TEXTURE_COMPARE_FUNC:
1445848b8605Smrg      if (!ctx->Extensions.ARB_shadow)
1446848b8605Smrg         goto invalid_pname;
1447848b8605Smrg      *params = sampObj->CompareFunc;
1448848b8605Smrg      break;
1449848b8605Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1450848b8605Smrg      *params = (GLint) sampObj->MaxAnisotropy;
1451848b8605Smrg      break;
1452848b8605Smrg   case GL_TEXTURE_BORDER_COLOR:
1453848b8605Smrg      params[0] = sampObj->BorderColor.i[0];
1454848b8605Smrg      params[1] = sampObj->BorderColor.i[1];
1455848b8605Smrg      params[2] = sampObj->BorderColor.i[2];
1456848b8605Smrg      params[3] = sampObj->BorderColor.i[3];
1457848b8605Smrg      break;
1458848b8605Smrg   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1459848b8605Smrg      if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
1460848b8605Smrg         goto invalid_pname;
1461848b8605Smrg      *params = sampObj->CubeMapSeamless;
1462848b8605Smrg      break;
1463848b8605Smrg   case GL_TEXTURE_SRGB_DECODE_EXT:
1464848b8605Smrg      if (!ctx->Extensions.EXT_texture_sRGB_decode)
1465848b8605Smrg         goto invalid_pname;
1466848b8605Smrg      *params = (GLenum) sampObj->sRGBDecode;
1467848b8605Smrg      break;
1468848b8605Smrg   default:
1469848b8605Smrg      goto invalid_pname;
1470848b8605Smrg   }
1471848b8605Smrg   return;
1472848b8605Smrg
1473848b8605Smrginvalid_pname:
1474848b8605Smrg   _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIiv(pname=%s)",
1475848b8605Smrg               _mesa_lookup_enum_by_nr(pname));
1476848b8605Smrg}
1477848b8605Smrg
1478848b8605Smrg
1479848b8605Smrgvoid GLAPIENTRY
1480848b8605Smrg_mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params)
1481848b8605Smrg{
1482848b8605Smrg   struct gl_sampler_object *sampObj;
1483848b8605Smrg   GET_CURRENT_CONTEXT(ctx);
1484848b8605Smrg
1485848b8605Smrg   sampObj = _mesa_lookup_samplerobj(ctx, sampler);
1486848b8605Smrg   if (!sampObj) {
1487848b8605Smrg      _mesa_error(ctx, GL_INVALID_VALUE,
1488848b8605Smrg                  "glGetSamplerParameterIuiv(sampler %u)",
1489848b8605Smrg                  sampler);
1490848b8605Smrg      return;
1491848b8605Smrg   }
1492848b8605Smrg
1493848b8605Smrg   switch (pname) {
1494848b8605Smrg   case GL_TEXTURE_WRAP_S:
1495848b8605Smrg      *params = sampObj->WrapS;
1496848b8605Smrg      break;
1497848b8605Smrg   case GL_TEXTURE_WRAP_T:
1498848b8605Smrg      *params = sampObj->WrapT;
1499848b8605Smrg      break;
1500848b8605Smrg   case GL_TEXTURE_WRAP_R:
1501848b8605Smrg      *params = sampObj->WrapR;
1502848b8605Smrg      break;
1503848b8605Smrg   case GL_TEXTURE_MIN_FILTER:
1504848b8605Smrg      *params = sampObj->MinFilter;
1505848b8605Smrg      break;
1506848b8605Smrg   case GL_TEXTURE_MAG_FILTER:
1507848b8605Smrg      *params = sampObj->MagFilter;
1508848b8605Smrg      break;
1509848b8605Smrg   case GL_TEXTURE_MIN_LOD:
1510848b8605Smrg      *params = (GLuint) sampObj->MinLod;
1511848b8605Smrg      break;
1512848b8605Smrg   case GL_TEXTURE_MAX_LOD:
1513848b8605Smrg      *params = (GLuint) sampObj->MaxLod;
1514848b8605Smrg      break;
1515848b8605Smrg   case GL_TEXTURE_LOD_BIAS:
1516848b8605Smrg      *params = (GLuint) sampObj->LodBias;
1517848b8605Smrg      break;
1518848b8605Smrg   case GL_TEXTURE_COMPARE_MODE:
1519848b8605Smrg      if (!ctx->Extensions.ARB_shadow)
1520848b8605Smrg         goto invalid_pname;
1521848b8605Smrg      *params = sampObj->CompareMode;
1522848b8605Smrg      break;
1523848b8605Smrg   case GL_TEXTURE_COMPARE_FUNC:
1524848b8605Smrg      if (!ctx->Extensions.ARB_shadow)
1525848b8605Smrg         goto invalid_pname;
1526848b8605Smrg      *params = sampObj->CompareFunc;
1527848b8605Smrg      break;
1528848b8605Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1529848b8605Smrg      *params = (GLuint) sampObj->MaxAnisotropy;
1530848b8605Smrg      break;
1531848b8605Smrg   case GL_TEXTURE_BORDER_COLOR:
1532848b8605Smrg      params[0] = sampObj->BorderColor.ui[0];
1533848b8605Smrg      params[1] = sampObj->BorderColor.ui[1];
1534848b8605Smrg      params[2] = sampObj->BorderColor.ui[2];
1535848b8605Smrg      params[3] = sampObj->BorderColor.ui[3];
1536848b8605Smrg      break;
1537848b8605Smrg   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1538848b8605Smrg      if (!ctx->Extensions.AMD_seamless_cubemap_per_texture)
1539848b8605Smrg         goto invalid_pname;
1540848b8605Smrg      *params = sampObj->CubeMapSeamless;
1541848b8605Smrg      break;
1542848b8605Smrg   case GL_TEXTURE_SRGB_DECODE_EXT:
1543848b8605Smrg      if (!ctx->Extensions.EXT_texture_sRGB_decode)
1544848b8605Smrg         goto invalid_pname;
1545848b8605Smrg      *params = (GLenum) sampObj->sRGBDecode;
1546848b8605Smrg      break;
1547848b8605Smrg   default:
1548848b8605Smrg      goto invalid_pname;
1549848b8605Smrg   }
1550848b8605Smrg   return;
1551848b8605Smrg
1552848b8605Smrginvalid_pname:
1553848b8605Smrg   _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIuiv(pname=%s)",
1554848b8605Smrg               _mesa_lookup_enum_by_nr(pname));
1555848b8605Smrg}
1556848b8605Smrg
1557848b8605Smrg
1558848b8605Smrgvoid
1559848b8605Smrg_mesa_init_sampler_object_functions(struct dd_function_table *driver)
1560848b8605Smrg{
1561848b8605Smrg   driver->NewSamplerObject = _mesa_new_sampler_object;
1562848b8605Smrg   driver->DeleteSamplerObject = _mesa_delete_sampler_object;
1563848b8605Smrg}
1564