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 "util/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 *
_mesa_lookup_samplerobj(struct gl_context * ctx,GLuint name)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 *
lookup_samplerobj_locked(struct gl_context * ctx,GLuint name)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
delete_sampler_object(struct gl_context * ctx,struct gl_sampler_object * sampObj)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
_mesa_reference_sampler_object_(struct gl_context * ctx,struct gl_sampler_object ** ptr,struct gl_sampler_object * samp)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
_mesa_init_sampler_object(struct gl_sampler_object * sampObj,GLuint name)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 *
_mesa_new_sampler_object(struct gl_context * ctx,GLuint name)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
create_samplers(struct gl_context * ctx,GLsizei count,GLuint * samplers,const char * caller)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);
196 }
197
198 _mesa_HashUnlockMutex(&ctx->Shared->SamplerObjects);
199 }
200
201 static void
create_samplers_err(struct gl_context * ctx,GLsizei count,GLuint * samplers,const char * caller)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
_mesa_GenSamplers_no_error(GLsizei count,GLuint * samplers)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
_mesa_GenSamplers(GLsizei count,GLuint * samplers)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
_mesa_CreateSamplers_no_error(GLsizei count,GLuint * samplers)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
_mesa_CreateSamplers(GLsizei count,GLuint * samplers)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
delete_samplers(struct gl_context * ctx,GLsizei count,const GLuint * samplers)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
_mesa_DeleteSamplers_no_error(GLsizei count,const GLuint * samplers)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
_mesa_DeleteSamplers(GLsizei count,const GLuint * samplers)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
_mesa_IsSampler(GLuint sampler)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
_mesa_bind_sampler(struct gl_context * ctx,GLuint unit,struct gl_sampler_object * sampObj)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
bind_sampler(struct gl_context * ctx,GLuint unit,GLuint sampler,bool no_error)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
_mesa_BindSampler_no_error(GLuint unit,GLuint sampler)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
_mesa_BindSampler(GLuint unit,GLuint sampler)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
bind_samplers(struct gl_context * ctx,GLuint first,GLsizei count,const GLuint * samplers,bool no_error)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
_mesa_BindSamplers_no_error(GLuint first,GLsizei count,const GLuint * samplers)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
_mesa_BindSamplers(GLuint first,GLsizei count,const GLuint * samplers)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
validate_texture_wrap_mode(struct gl_context * ctx,GLenum wrap)491 validate_texture_wrap_mode(struct gl_context *ctx, GLenum wrap)
492 {
493 const struct gl_extensions * const e = &ctx->Extensions;
494
495 bool mirror_clamp =
496 _mesa_has_ATI_texture_mirror_once(ctx) ||
497 _mesa_has_EXT_texture_mirror_clamp(ctx);
498
499 bool mirror_clamp_to_edge =
500 _mesa_has_ARB_texture_mirror_clamp_to_edge(ctx) ||
501 _mesa_has_EXT_texture_mirror_clamp_to_edge(ctx) ||
502 mirror_clamp;
503
504 switch (wrap) {
505 case GL_CLAMP:
506 /* From GL 3.0 specification section E.1 "Profiles and Deprecated
507 * Features of OpenGL 3.0":
508 *
509 * - Texture wrap mode CLAMP - CLAMP is no longer accepted as a value of
510 * texture parameters TEXTURE_WRAP_S, TEXTURE_WRAP_T, or
511 * TEXTURE_WRAP_R.
512 */
513 return _mesa_is_desktop_gl_compat(ctx);
514 case GL_CLAMP_TO_EDGE:
515 case GL_REPEAT:
516 case GL_MIRRORED_REPEAT:
517 case GL_CLAMP_TO_BORDER:
518 return GL_TRUE;
519 case GL_MIRROR_CLAMP_EXT:
520 return mirror_clamp;
521 case GL_MIRROR_CLAMP_TO_EDGE_EXT:
522 return mirror_clamp_to_edge;
523 case GL_MIRROR_CLAMP_TO_BORDER_EXT:
524 return e->EXT_texture_mirror_clamp;
525 default:
526 return GL_FALSE;
527 }
528 }
529
530
531 /**
532 * This is called just prior to changing any sampler object state.
533 */
534 static inline void
flush(struct gl_context * ctx)535 flush(struct gl_context *ctx)
536 {
537 FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT);
538 }
539
540 #define INVALID_PARAM 0x100
541 #define INVALID_PNAME 0x101
542 #define INVALID_VALUE 0x102
543
544 static GLuint
set_sampler_wrap_s(struct gl_context * ctx,struct gl_sampler_object * samp,GLint param)545 set_sampler_wrap_s(struct gl_context *ctx, struct gl_sampler_object *samp,
546 GLint param)
547 {
548 if (samp->Attrib.WrapS == param)
549 return GL_FALSE;
550 if (validate_texture_wrap_mode(ctx, param)) {
551 flush(ctx);
552 update_sampler_gl_clamp(ctx, samp, is_wrap_gl_clamp(samp->Attrib.WrapS), is_wrap_gl_clamp(param), WRAP_S);
553 samp->Attrib.WrapS = param;
554 samp->Attrib.state.wrap_s = wrap_to_gallium(param);
555 _mesa_lower_gl_clamp(ctx, samp);
556 return GL_TRUE;
557 }
558 return INVALID_PARAM;
559 }
560
561
562 static GLuint
set_sampler_wrap_t(struct gl_context * ctx,struct gl_sampler_object * samp,GLint param)563 set_sampler_wrap_t(struct gl_context *ctx, struct gl_sampler_object *samp,
564 GLint param)
565 {
566 if (samp->Attrib.WrapT == param)
567 return GL_FALSE;
568 if (validate_texture_wrap_mode(ctx, param)) {
569 flush(ctx);
570 update_sampler_gl_clamp(ctx, samp, is_wrap_gl_clamp(samp->Attrib.WrapT), is_wrap_gl_clamp(param), WRAP_T);
571 samp->Attrib.WrapT = param;
572 samp->Attrib.state.wrap_t = wrap_to_gallium(param);
573 _mesa_lower_gl_clamp(ctx, samp);
574 return GL_TRUE;
575 }
576 return INVALID_PARAM;
577 }
578
579
580 static GLuint
set_sampler_wrap_r(struct gl_context * ctx,struct gl_sampler_object * samp,GLint param)581 set_sampler_wrap_r(struct gl_context *ctx, struct gl_sampler_object *samp,
582 GLint param)
583 {
584 if (samp->Attrib.WrapR == param)
585 return GL_FALSE;
586 if (validate_texture_wrap_mode(ctx, param)) {
587 flush(ctx);
588 update_sampler_gl_clamp(ctx, samp, is_wrap_gl_clamp(samp->Attrib.WrapR), is_wrap_gl_clamp(param), WRAP_R);
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
set_sampler_min_filter(struct gl_context * ctx,struct gl_sampler_object * samp,GLint param)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
set_sampler_mag_filter(struct gl_context * ctx,struct gl_sampler_object * samp,GLint param)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
set_sampler_lod_bias(struct gl_context * ctx,struct gl_sampler_object * samp,GLfloat param)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
set_sampler_border_colorf(struct gl_context * ctx,struct gl_sampler_object * samp,const GLfloat params[4])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
set_sampler_border_colori(struct gl_context * ctx,struct gl_sampler_object * samp,const GLint params[4])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
set_sampler_border_colorui(struct gl_context * ctx,struct gl_sampler_object * samp,const GLuint params[4])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
set_sampler_min_lod(struct gl_context * ctx,struct gl_sampler_object * samp,GLfloat param)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
set_sampler_max_lod(struct gl_context * ctx,struct gl_sampler_object * samp,GLfloat param)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
set_sampler_compare_mode(struct gl_context * ctx,struct gl_sampler_object * samp,GLint param)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
set_sampler_compare_func(struct gl_context * ctx,struct gl_sampler_object * samp,GLint param)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
set_sampler_max_anisotropy(struct gl_context * ctx,struct gl_sampler_object * samp,GLfloat param)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
set_sampler_cube_map_seamless(struct gl_context * ctx,struct gl_sampler_object * samp,GLboolean param)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
set_sampler_srgb_decode(struct gl_context * ctx,struct gl_sampler_object * samp,GLenum param)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
set_sampler_reduction_mode(struct gl_context * ctx,struct gl_sampler_object * samp,GLenum param)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 *
sampler_parameter_error_check(struct gl_context * ctx,GLuint sampler,bool get,const char * name)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
_mesa_SamplerParameteri(GLuint sampler,GLenum pname,GLint param)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
_mesa_SamplerParameterf(GLuint sampler,GLenum pname,GLfloat param)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
_mesa_SamplerParameteriv(GLuint sampler,GLenum pname,const GLint * params)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
_mesa_SamplerParameterfv(GLuint sampler,GLenum pname,const GLfloat * params)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
_mesa_SamplerParameterIiv(GLuint sampler,GLenum pname,const GLint * params)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
_mesa_SamplerParameterIuiv(GLuint sampler,GLenum pname,const GLuint * params)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
_mesa_GetSamplerParameteriv(GLuint sampler,GLenum pname,GLint * params)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
_mesa_GetSamplerParameterfv(GLuint sampler,GLenum pname,GLfloat * params)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
_mesa_GetSamplerParameterIiv(GLuint sampler,GLenum pname,GLint * params)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
_mesa_GetSamplerParameterIuiv(GLuint sampler,GLenum pname,GLuint * params)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 }
1758