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