Rev 4358 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4358 | Serge | 1 | /* |
2 | * Mesa 3-D graphics library |
||
3 | * |
||
4 | * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. |
||
5 | * Copyright (C) 2009 VMware, Inc. All Rights Reserved. |
||
6 | * |
||
7 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
8 | * copy of this software and associated documentation files (the "Software"), |
||
9 | * to deal in the Software without restriction, including without limitation |
||
10 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||
11 | * and/or sell copies of the Software, and to permit persons to whom the |
||
12 | * Software is furnished to do so, subject to the following conditions: |
||
13 | * |
||
14 | * The above copyright notice and this permission notice shall be included |
||
15 | * in all copies or substantial portions of the Software. |
||
16 | * |
||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||
18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
||
21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
||
22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
||
23 | * OTHER DEALINGS IN THE SOFTWARE. |
||
24 | */ |
||
25 | |||
26 | /** |
||
27 | * \file texparam.c |
||
28 | * |
||
29 | * glTexParameter-related functions |
||
30 | */ |
||
31 | |||
32 | #include |
||
33 | #include "main/glheader.h" |
||
34 | #include "main/blend.h" |
||
35 | #include "main/colormac.h" |
||
36 | #include "main/context.h" |
||
37 | #include "main/enums.h" |
||
38 | #include "main/formats.h" |
||
39 | #include "main/glformats.h" |
||
40 | #include "main/macros.h" |
||
41 | #include "main/mtypes.h" |
||
42 | #include "main/state.h" |
||
43 | #include "main/texcompress.h" |
||
44 | #include "main/texobj.h" |
||
45 | #include "main/texparam.h" |
||
46 | #include "main/teximage.h" |
||
47 | #include "main/texstate.h" |
||
48 | #include "program/prog_instruction.h" |
||
49 | |||
50 | |||
51 | /** |
||
52 | * Check if a coordinate wrap mode is supported for the texture target. |
||
53 | * \return GL_TRUE if legal, GL_FALSE otherwise |
||
54 | */ |
||
55 | static GLboolean |
||
56 | validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap) |
||
57 | { |
||
58 | const struct gl_extensions * const e = & ctx->Extensions; |
||
59 | const bool is_desktop_gl = _mesa_is_desktop_gl(ctx); |
||
60 | bool supported; |
||
61 | |||
62 | switch (wrap) { |
||
63 | case GL_CLAMP: |
||
64 | /* GL_CLAMP was removed in the core profile, and it has never existed in |
||
65 | * OpenGL ES. |
||
66 | */ |
||
67 | supported = (ctx->API == API_OPENGL_COMPAT) |
||
68 | && (target != GL_TEXTURE_EXTERNAL_OES); |
||
69 | break; |
||
70 | |||
71 | case GL_CLAMP_TO_EDGE: |
||
72 | supported = true; |
||
73 | break; |
||
74 | |||
75 | case GL_CLAMP_TO_BORDER: |
||
76 | supported = is_desktop_gl && e->ARB_texture_border_clamp |
||
77 | && (target != GL_TEXTURE_EXTERNAL_OES); |
||
78 | break; |
||
79 | |||
80 | case GL_REPEAT: |
||
81 | case GL_MIRRORED_REPEAT: |
||
82 | supported = (target != GL_TEXTURE_RECTANGLE_NV) |
||
83 | && (target != GL_TEXTURE_EXTERNAL_OES); |
||
84 | break; |
||
85 | |||
86 | case GL_MIRROR_CLAMP_EXT: |
||
87 | case GL_MIRROR_CLAMP_TO_EDGE_EXT: |
||
88 | supported = is_desktop_gl |
||
89 | && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp) |
||
90 | && (target != GL_TEXTURE_RECTANGLE_NV) |
||
91 | && (target != GL_TEXTURE_EXTERNAL_OES); |
||
92 | break; |
||
93 | |||
94 | case GL_MIRROR_CLAMP_TO_BORDER_EXT: |
||
95 | supported = is_desktop_gl && e->EXT_texture_mirror_clamp |
||
96 | && (target != GL_TEXTURE_RECTANGLE_NV) |
||
97 | && (target != GL_TEXTURE_EXTERNAL_OES); |
||
98 | break; |
||
99 | |||
100 | default: |
||
101 | supported = false; |
||
102 | break; |
||
103 | } |
||
104 | |||
105 | if (!supported) |
||
106 | _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap ); |
||
107 | |||
108 | return supported; |
||
109 | } |
||
110 | |||
111 | |||
112 | /** |
||
113 | * Get current texture object for given target. |
||
114 | * Return NULL if any error (and record the error). |
||
115 | * Note that this is different from _mesa_select_tex_object() in that proxy |
||
116 | * targets are not accepted. |
||
117 | * Only the glGetTexLevelParameter() functions accept proxy targets. |
||
118 | */ |
||
119 | static struct gl_texture_object * |
||
120 | get_texobj(struct gl_context *ctx, GLenum target, GLboolean get) |
||
121 | { |
||
122 | struct gl_texture_unit *texUnit; |
||
123 | |||
124 | if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) { |
||
125 | _mesa_error(ctx, GL_INVALID_OPERATION, |
||
126 | "gl%sTexParameter(current unit)", get ? "Get" : ""); |
||
127 | return NULL; |
||
128 | } |
||
129 | |||
130 | texUnit = _mesa_get_current_tex_unit(ctx); |
||
131 | |||
132 | switch (target) { |
||
133 | case GL_TEXTURE_1D: |
||
134 | if (_mesa_is_desktop_gl(ctx)) |
||
135 | return texUnit->CurrentTex[TEXTURE_1D_INDEX]; |
||
136 | break; |
||
137 | case GL_TEXTURE_2D: |
||
138 | return texUnit->CurrentTex[TEXTURE_2D_INDEX]; |
||
139 | case GL_TEXTURE_3D: |
||
140 | if (ctx->API != API_OPENGLES) |
||
141 | return texUnit->CurrentTex[TEXTURE_3D_INDEX]; |
||
142 | break; |
||
143 | case GL_TEXTURE_CUBE_MAP: |
||
144 | if (ctx->Extensions.ARB_texture_cube_map) { |
||
145 | return texUnit->CurrentTex[TEXTURE_CUBE_INDEX]; |
||
146 | } |
||
147 | break; |
||
148 | case GL_TEXTURE_RECTANGLE_NV: |
||
149 | if (_mesa_is_desktop_gl(ctx) |
||
150 | && ctx->Extensions.NV_texture_rectangle) { |
||
151 | return texUnit->CurrentTex[TEXTURE_RECT_INDEX]; |
||
152 | } |
||
153 | break; |
||
154 | case GL_TEXTURE_1D_ARRAY_EXT: |
||
155 | if (_mesa_is_desktop_gl(ctx) |
||
156 | && (ctx->Extensions.MESA_texture_array || |
||
157 | ctx->Extensions.EXT_texture_array)) { |
||
158 | return texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX]; |
||
159 | } |
||
160 | break; |
||
161 | case GL_TEXTURE_2D_ARRAY_EXT: |
||
162 | if ((_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) |
||
163 | && (ctx->Extensions.MESA_texture_array || |
||
164 | ctx->Extensions.EXT_texture_array)) { |
||
165 | return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX]; |
||
166 | } |
||
167 | break; |
||
168 | case GL_TEXTURE_EXTERNAL_OES: |
||
169 | if (_mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external) { |
||
170 | return texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX]; |
||
171 | } |
||
172 | break; |
||
173 | case GL_TEXTURE_CUBE_MAP_ARRAY: |
||
174 | if (ctx->Extensions.ARB_texture_cube_map_array) { |
||
175 | return texUnit->CurrentTex[TEXTURE_CUBE_ARRAY_INDEX]; |
||
176 | } |
||
177 | break; |
||
178 | case GL_TEXTURE_2D_MULTISAMPLE: |
||
179 | if (ctx->Extensions.ARB_texture_multisample) { |
||
180 | return texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_INDEX]; |
||
181 | } |
||
182 | break; |
||
183 | case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: |
||
184 | if (ctx->Extensions.ARB_texture_multisample) { |
||
185 | return texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX]; |
||
186 | } |
||
187 | break; |
||
188 | default: |
||
189 | ; |
||
190 | } |
||
191 | |||
192 | _mesa_error(ctx, GL_INVALID_ENUM, |
||
193 | "gl%sTexParameter(target)", get ? "Get" : ""); |
||
194 | return NULL; |
||
195 | } |
||
196 | |||
197 | |||
198 | /** |
||
199 | * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE. |
||
200 | * \return -1 if error. |
||
201 | */ |
||
202 | static GLint |
||
203 | comp_to_swizzle(GLenum comp) |
||
204 | { |
||
205 | switch (comp) { |
||
206 | case GL_RED: |
||
207 | return SWIZZLE_X; |
||
208 | case GL_GREEN: |
||
209 | return SWIZZLE_Y; |
||
210 | case GL_BLUE: |
||
211 | return SWIZZLE_Z; |
||
212 | case GL_ALPHA: |
||
213 | return SWIZZLE_W; |
||
214 | case GL_ZERO: |
||
215 | return SWIZZLE_ZERO; |
||
216 | case GL_ONE: |
||
217 | return SWIZZLE_ONE; |
||
218 | default: |
||
219 | return -1; |
||
220 | } |
||
221 | } |
||
222 | |||
223 | |||
224 | static void |
||
225 | set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz) |
||
226 | { |
||
227 | ASSERT(comp < 4); |
||
228 | ASSERT(swz <= SWIZZLE_NIL); |
||
229 | { |
||
230 | GLuint mask = 0x7 << (3 * comp); |
||
231 | GLuint s = (*swizzle & ~mask) | (swz << (3 * comp)); |
||
232 | *swizzle = s; |
||
233 | } |
||
234 | } |
||
235 | |||
236 | |||
237 | /** |
||
238 | * This is called just prior to changing any texture object state which |
||
239 | * will not effect texture completeness. |
||
240 | */ |
||
241 | static inline void |
||
242 | flush(struct gl_context *ctx) |
||
243 | { |
||
244 | FLUSH_VERTICES(ctx, _NEW_TEXTURE); |
||
245 | } |
||
246 | |||
247 | |||
248 | /** |
||
249 | * This is called just prior to changing any texture object state which |
||
250 | * can effect texture completeness (texture base level, max level). |
||
251 | * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE |
||
252 | * state flag and then mark the texture object as 'incomplete' so that any |
||
253 | * per-texture derived state gets recomputed. |
||
254 | */ |
||
255 | static inline void |
||
256 | incomplete(struct gl_context *ctx, struct gl_texture_object *texObj) |
||
257 | { |
||
258 | FLUSH_VERTICES(ctx, _NEW_TEXTURE); |
||
259 | _mesa_dirty_texobj(ctx, texObj, GL_TRUE); |
||
260 | } |
||
261 | |||
262 | |||
263 | static GLboolean |
||
264 | target_allows_setting_sampler_parameters(GLenum target) |
||
265 | { |
||
266 | switch (target) { |
||
267 | case GL_TEXTURE_2D_MULTISAMPLE: |
||
268 | case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: |
||
269 | return GL_FALSE; |
||
270 | |||
271 | default: |
||
272 | return GL_TRUE; |
||
273 | } |
||
274 | } |
||
275 | |||
276 | |||
277 | /** |
||
278 | * Set an integer-valued texture parameter |
||
279 | * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise |
||
280 | */ |
||
281 | static GLboolean |
||
282 | set_tex_parameteri(struct gl_context *ctx, |
||
283 | struct gl_texture_object *texObj, |
||
284 | GLenum pname, const GLint *params) |
||
285 | { |
||
286 | switch (pname) { |
||
287 | case GL_TEXTURE_MIN_FILTER: |
||
288 | if (!target_allows_setting_sampler_parameters(texObj->Target)) |
||
289 | goto invalid_operation; |
||
290 | |||
291 | if (texObj->Sampler.MinFilter == params[0]) |
||
292 | return GL_FALSE; |
||
293 | switch (params[0]) { |
||
294 | case GL_NEAREST: |
||
295 | case GL_LINEAR: |
||
296 | flush(ctx); |
||
297 | texObj->Sampler.MinFilter = params[0]; |
||
298 | return GL_TRUE; |
||
299 | case GL_NEAREST_MIPMAP_NEAREST: |
||
300 | case GL_LINEAR_MIPMAP_NEAREST: |
||
301 | case GL_NEAREST_MIPMAP_LINEAR: |
||
302 | case GL_LINEAR_MIPMAP_LINEAR: |
||
303 | if (texObj->Target != GL_TEXTURE_RECTANGLE_NV && |
||
304 | texObj->Target != GL_TEXTURE_EXTERNAL_OES) { |
||
305 | flush(ctx); |
||
306 | texObj->Sampler.MinFilter = params[0]; |
||
307 | return GL_TRUE; |
||
308 | } |
||
309 | /* fall-through */ |
||
310 | default: |
||
311 | goto invalid_param; |
||
312 | } |
||
313 | return GL_FALSE; |
||
314 | |||
315 | case GL_TEXTURE_MAG_FILTER: |
||
316 | if (!target_allows_setting_sampler_parameters(texObj->Target)) |
||
317 | goto invalid_operation; |
||
318 | |||
319 | if (texObj->Sampler.MagFilter == params[0]) |
||
320 | return GL_FALSE; |
||
321 | switch (params[0]) { |
||
322 | case GL_NEAREST: |
||
323 | case GL_LINEAR: |
||
324 | flush(ctx); /* does not effect completeness */ |
||
325 | texObj->Sampler.MagFilter = params[0]; |
||
326 | return GL_TRUE; |
||
327 | default: |
||
328 | goto invalid_param; |
||
329 | } |
||
330 | return GL_FALSE; |
||
331 | |||
332 | case GL_TEXTURE_WRAP_S: |
||
333 | if (!target_allows_setting_sampler_parameters(texObj->Target)) |
||
334 | goto invalid_operation; |
||
335 | |||
336 | if (texObj->Sampler.WrapS == params[0]) |
||
337 | return GL_FALSE; |
||
338 | if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { |
||
339 | flush(ctx); |
||
340 | texObj->Sampler.WrapS = params[0]; |
||
341 | return GL_TRUE; |
||
342 | } |
||
343 | return GL_FALSE; |
||
344 | |||
345 | case GL_TEXTURE_WRAP_T: |
||
346 | if (!target_allows_setting_sampler_parameters(texObj->Target)) |
||
347 | goto invalid_operation; |
||
348 | |||
349 | if (texObj->Sampler.WrapT == params[0]) |
||
350 | return GL_FALSE; |
||
351 | if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { |
||
352 | flush(ctx); |
||
353 | texObj->Sampler.WrapT = params[0]; |
||
354 | return GL_TRUE; |
||
355 | } |
||
356 | return GL_FALSE; |
||
357 | |||
358 | case GL_TEXTURE_WRAP_R: |
||
359 | if (!target_allows_setting_sampler_parameters(texObj->Target)) |
||
360 | goto invalid_operation; |
||
361 | |||
362 | if (texObj->Sampler.WrapR == params[0]) |
||
363 | return GL_FALSE; |
||
364 | if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { |
||
365 | flush(ctx); |
||
366 | texObj->Sampler.WrapR = params[0]; |
||
367 | return GL_TRUE; |
||
368 | } |
||
369 | return GL_FALSE; |
||
370 | |||
371 | case GL_TEXTURE_BASE_LEVEL: |
||
372 | if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) |
||
373 | goto invalid_pname; |
||
374 | |||
375 | if (texObj->BaseLevel == params[0]) |
||
376 | return GL_FALSE; |
||
377 | |||
378 | if ((texObj->Target == GL_TEXTURE_2D_MULTISAMPLE || |
||
379 | texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && params[0] != 0) |
||
380 | goto invalid_operation; |
||
381 | |||
382 | if (params[0] < 0 || |
||
383 | (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) { |
||
384 | _mesa_error(ctx, GL_INVALID_VALUE, |
||
385 | "glTexParameter(param=%d)", params[0]); |
||
386 | return GL_FALSE; |
||
387 | } |
||
388 | incomplete(ctx, texObj); |
||
389 | texObj->BaseLevel = params[0]; |
||
390 | return GL_TRUE; |
||
391 | |||
392 | case GL_TEXTURE_MAX_LEVEL: |
||
393 | if (texObj->MaxLevel == params[0]) |
||
394 | return GL_FALSE; |
||
395 | |||
396 | if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) { |
||
397 | _mesa_error(ctx, GL_INVALID_VALUE, |
||
398 | "glTexParameter(param=%d)", params[0]); |
||
399 | return GL_FALSE; |
||
400 | } |
||
401 | incomplete(ctx, texObj); |
||
402 | texObj->MaxLevel = params[0]; |
||
403 | return GL_TRUE; |
||
404 | |||
405 | case GL_GENERATE_MIPMAP_SGIS: |
||
406 | if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) |
||
407 | goto invalid_pname; |
||
408 | |||
409 | if (params[0] && texObj->Target == GL_TEXTURE_EXTERNAL_OES) |
||
410 | goto invalid_param; |
||
411 | if (texObj->GenerateMipmap != params[0]) { |
||
412 | /* no flush() */ |
||
413 | texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE; |
||
414 | return GL_TRUE; |
||
415 | } |
||
416 | return GL_FALSE; |
||
417 | |||
418 | case GL_TEXTURE_COMPARE_MODE_ARB: |
||
419 | if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow) |
||
420 | || _mesa_is_gles3(ctx)) { |
||
421 | |||
422 | if (!target_allows_setting_sampler_parameters(texObj->Target)) |
||
423 | goto invalid_operation; |
||
424 | |||
425 | if (texObj->Sampler.CompareMode == params[0]) |
||
426 | return GL_FALSE; |
||
427 | if (params[0] == GL_NONE || |
||
428 | params[0] == GL_COMPARE_R_TO_TEXTURE_ARB) { |
||
429 | flush(ctx); |
||
430 | texObj->Sampler.CompareMode = params[0]; |
||
431 | return GL_TRUE; |
||
432 | } |
||
433 | goto invalid_param; |
||
434 | } |
||
435 | goto invalid_pname; |
||
436 | |||
437 | case GL_TEXTURE_COMPARE_FUNC_ARB: |
||
438 | if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow) |
||
439 | || _mesa_is_gles3(ctx)) { |
||
440 | |||
441 | if (!target_allows_setting_sampler_parameters(texObj->Target)) |
||
442 | goto invalid_operation; |
||
443 | |||
444 | if (texObj->Sampler.CompareFunc == params[0]) |
||
445 | return GL_FALSE; |
||
446 | switch (params[0]) { |
||
447 | case GL_LEQUAL: |
||
448 | case GL_GEQUAL: |
||
449 | case GL_EQUAL: |
||
450 | case GL_NOTEQUAL: |
||
451 | case GL_LESS: |
||
452 | case GL_GREATER: |
||
453 | case GL_ALWAYS: |
||
454 | case GL_NEVER: |
||
455 | flush(ctx); |
||
456 | texObj->Sampler.CompareFunc = params[0]; |
||
457 | return GL_TRUE; |
||
458 | default: |
||
459 | goto invalid_param; |
||
460 | } |
||
461 | } |
||
462 | goto invalid_pname; |
||
463 | |||
464 | case GL_DEPTH_TEXTURE_MODE_ARB: |
||
465 | /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has never |
||
466 | * existed in OpenGL ES. |
||
467 | */ |
||
468 | if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_depth_texture) { |
||
469 | if (texObj->DepthMode == params[0]) |
||
470 | return GL_FALSE; |
||
471 | if (params[0] == GL_LUMINANCE || |
||
472 | params[0] == GL_INTENSITY || |
||
473 | params[0] == GL_ALPHA || |
||
474 | (ctx->Extensions.ARB_texture_rg && params[0] == GL_RED)) { |
||
475 | flush(ctx); |
||
476 | texObj->DepthMode = params[0]; |
||
477 | return GL_TRUE; |
||
478 | } |
||
479 | goto invalid_param; |
||
480 | } |
||
481 | goto invalid_pname; |
||
482 | |||
483 | case GL_TEXTURE_CROP_RECT_OES: |
||
484 | if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture) |
||
485 | goto invalid_pname; |
||
486 | |||
487 | texObj->CropRect[0] = params[0]; |
||
488 | texObj->CropRect[1] = params[1]; |
||
489 | texObj->CropRect[2] = params[2]; |
||
490 | texObj->CropRect[3] = params[3]; |
||
491 | return GL_TRUE; |
||
492 | |||
493 | case GL_TEXTURE_SWIZZLE_R_EXT: |
||
494 | case GL_TEXTURE_SWIZZLE_G_EXT: |
||
495 | case GL_TEXTURE_SWIZZLE_B_EXT: |
||
496 | case GL_TEXTURE_SWIZZLE_A_EXT: |
||
497 | if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle) |
||
498 | || _mesa_is_gles3(ctx)) { |
||
499 | const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT; |
||
500 | const GLint swz = comp_to_swizzle(params[0]); |
||
501 | if (swz < 0) { |
||
502 | _mesa_error(ctx, GL_INVALID_OPERATION, |
||
503 | "glTexParameter(swizzle 0x%x)", params[0]); |
||
504 | return GL_FALSE; |
||
505 | } |
||
506 | ASSERT(comp < 4); |
||
507 | |||
508 | flush(ctx); |
||
509 | texObj->Swizzle[comp] = params[0]; |
||
510 | set_swizzle_component(&texObj->_Swizzle, comp, swz); |
||
511 | return GL_TRUE; |
||
512 | } |
||
513 | goto invalid_pname; |
||
514 | |||
515 | case GL_TEXTURE_SWIZZLE_RGBA_EXT: |
||
516 | if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle) |
||
517 | || _mesa_is_gles3(ctx)) { |
||
518 | GLuint comp; |
||
519 | flush(ctx); |
||
520 | for (comp = 0; comp < 4; comp++) { |
||
521 | const GLint swz = comp_to_swizzle(params[comp]); |
||
522 | if (swz >= 0) { |
||
523 | texObj->Swizzle[comp] = params[comp]; |
||
524 | set_swizzle_component(&texObj->_Swizzle, comp, swz); |
||
525 | } |
||
526 | else { |
||
527 | _mesa_error(ctx, GL_INVALID_OPERATION, |
||
528 | "glTexParameter(swizzle 0x%x)", params[comp]); |
||
529 | return GL_FALSE; |
||
530 | } |
||
531 | } |
||
532 | return GL_TRUE; |
||
533 | } |
||
534 | goto invalid_pname; |
||
535 | |||
536 | case GL_TEXTURE_SRGB_DECODE_EXT: |
||
537 | if (_mesa_is_desktop_gl(ctx) |
||
538 | && ctx->Extensions.EXT_texture_sRGB_decode) { |
||
539 | GLenum decode = params[0]; |
||
540 | |||
541 | if (!target_allows_setting_sampler_parameters(texObj->Target)) |
||
542 | goto invalid_operation; |
||
543 | |||
544 | if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) { |
||
545 | if (texObj->Sampler.sRGBDecode != decode) { |
||
546 | flush(ctx); |
||
547 | texObj->Sampler.sRGBDecode = decode; |
||
548 | } |
||
549 | return GL_TRUE; |
||
550 | } |
||
551 | } |
||
552 | goto invalid_pname; |
||
553 | |||
554 | case GL_TEXTURE_CUBE_MAP_SEAMLESS: |
||
555 | if (_mesa_is_desktop_gl(ctx) |
||
556 | && ctx->Extensions.AMD_seamless_cubemap_per_texture) { |
||
557 | GLenum param = params[0]; |
||
558 | |||
559 | if (!target_allows_setting_sampler_parameters(texObj->Target)) |
||
560 | goto invalid_operation; |
||
561 | |||
562 | if (param != GL_TRUE && param != GL_FALSE) { |
||
563 | goto invalid_param; |
||
564 | } |
||
565 | if (param != texObj->Sampler.CubeMapSeamless) { |
||
566 | flush(ctx); |
||
567 | texObj->Sampler.CubeMapSeamless = param; |
||
568 | } |
||
569 | return GL_TRUE; |
||
570 | } |
||
571 | goto invalid_pname; |
||
572 | |||
573 | default: |
||
574 | goto invalid_pname; |
||
575 | } |
||
576 | |||
577 | invalid_pname: |
||
578 | _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)", |
||
579 | _mesa_lookup_enum_by_nr(pname)); |
||
580 | return GL_FALSE; |
||
581 | |||
582 | invalid_param: |
||
583 | _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param=%s)", |
||
584 | _mesa_lookup_enum_by_nr(params[0])); |
||
585 | return GL_FALSE; |
||
586 | |||
587 | invalid_operation: |
||
588 | _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)", |
||
589 | _mesa_lookup_enum_by_nr(pname)); |
||
590 | return GL_FALSE; |
||
591 | } |
||
592 | |||
593 | |||
594 | /** |
||
595 | * Set a float-valued texture parameter |
||
596 | * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise |
||
597 | */ |
||
598 | static GLboolean |
||
599 | set_tex_parameterf(struct gl_context *ctx, |
||
600 | struct gl_texture_object *texObj, |
||
601 | GLenum pname, const GLfloat *params) |
||
602 | { |
||
603 | switch (pname) { |
||
604 | case GL_TEXTURE_MIN_LOD: |
||
605 | if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) |
||
606 | goto invalid_pname; |
||
607 | |||
608 | if (!target_allows_setting_sampler_parameters(texObj->Target)) |
||
609 | goto invalid_operation; |
||
610 | |||
611 | if (texObj->Sampler.MinLod == params[0]) |
||
612 | return GL_FALSE; |
||
613 | flush(ctx); |
||
614 | texObj->Sampler.MinLod = params[0]; |
||
615 | return GL_TRUE; |
||
616 | |||
617 | case GL_TEXTURE_MAX_LOD: |
||
618 | if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) |
||
619 | goto invalid_pname; |
||
620 | |||
621 | if (!target_allows_setting_sampler_parameters(texObj->Target)) |
||
622 | goto invalid_operation; |
||
623 | |||
624 | if (texObj->Sampler.MaxLod == params[0]) |
||
625 | return GL_FALSE; |
||
626 | flush(ctx); |
||
627 | texObj->Sampler.MaxLod = params[0]; |
||
628 | return GL_TRUE; |
||
629 | |||
630 | case GL_TEXTURE_PRIORITY: |
||
631 | if (ctx->API != API_OPENGL_COMPAT) |
||
632 | goto invalid_pname; |
||
633 | |||
634 | flush(ctx); |
||
635 | texObj->Priority = CLAMP(params[0], 0.0F, 1.0F); |
||
636 | return GL_TRUE; |
||
637 | |||
638 | case GL_TEXTURE_MAX_ANISOTROPY_EXT: |
||
639 | if (ctx->Extensions.EXT_texture_filter_anisotropic) { |
||
640 | if (!target_allows_setting_sampler_parameters(texObj->Target)) |
||
641 | goto invalid_operation; |
||
642 | |||
643 | if (texObj->Sampler.MaxAnisotropy == params[0]) |
||
644 | return GL_FALSE; |
||
645 | if (params[0] < 1.0) { |
||
646 | _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); |
||
647 | return GL_FALSE; |
||
648 | } |
||
649 | flush(ctx); |
||
650 | /* clamp to max, that's what NVIDIA does */ |
||
651 | texObj->Sampler.MaxAnisotropy = MIN2(params[0], |
||
652 | ctx->Const.MaxTextureMaxAnisotropy); |
||
653 | return GL_TRUE; |
||
654 | } |
||
655 | else { |
||
656 | static GLuint count = 0; |
||
657 | if (count++ < 10) |
||
658 | goto invalid_pname; |
||
659 | } |
||
660 | return GL_FALSE; |
||
661 | |||
662 | case GL_TEXTURE_LOD_BIAS: |
||
4401 | Serge | 663 | /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias. */ |
664 | if (_mesa_is_gles(ctx)) |
||
4358 | Serge | 665 | goto invalid_pname; |
666 | |||
667 | if (!target_allows_setting_sampler_parameters(texObj->Target)) |
||
668 | goto invalid_operation; |
||
669 | |||
670 | if (texObj->Sampler.LodBias != params[0]) { |
||
671 | flush(ctx); |
||
672 | texObj->Sampler.LodBias = params[0]; |
||
673 | return GL_TRUE; |
||
674 | } |
||
675 | break; |
||
676 | |||
677 | case GL_TEXTURE_BORDER_COLOR: |
||
678 | if (!_mesa_is_desktop_gl(ctx)) |
||
679 | goto invalid_pname; |
||
680 | |||
681 | if (!target_allows_setting_sampler_parameters(texObj->Target)) |
||
682 | goto invalid_operation; |
||
683 | |||
684 | flush(ctx); |
||
685 | /* ARB_texture_float disables clamping */ |
||
686 | if (ctx->Extensions.ARB_texture_float) { |
||
687 | texObj->Sampler.BorderColor.f[RCOMP] = params[0]; |
||
688 | texObj->Sampler.BorderColor.f[GCOMP] = params[1]; |
||
689 | texObj->Sampler.BorderColor.f[BCOMP] = params[2]; |
||
690 | texObj->Sampler.BorderColor.f[ACOMP] = params[3]; |
||
691 | } else { |
||
692 | texObj->Sampler.BorderColor.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F); |
||
693 | texObj->Sampler.BorderColor.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F); |
||
694 | texObj->Sampler.BorderColor.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F); |
||
695 | texObj->Sampler.BorderColor.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F); |
||
696 | } |
||
697 | return GL_TRUE; |
||
698 | |||
699 | default: |
||
700 | goto invalid_pname; |
||
701 | } |
||
702 | return GL_FALSE; |
||
703 | |||
704 | invalid_pname: |
||
705 | _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)", |
||
706 | _mesa_lookup_enum_by_nr(pname)); |
||
707 | return GL_FALSE; |
||
708 | |||
709 | invalid_operation: |
||
710 | _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)", |
||
711 | _mesa_lookup_enum_by_nr(pname)); |
||
712 | return GL_FALSE; |
||
713 | } |
||
714 | |||
715 | |||
716 | void GLAPIENTRY |
||
717 | _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) |
||
718 | { |
||
719 | GLboolean need_update; |
||
720 | struct gl_texture_object *texObj; |
||
721 | GET_CURRENT_CONTEXT(ctx); |
||
722 | |||
723 | texObj = get_texobj(ctx, target, GL_FALSE); |
||
724 | if (!texObj) |
||
725 | return; |
||
726 | |||
727 | switch (pname) { |
||
728 | case GL_TEXTURE_MIN_FILTER: |
||
729 | case GL_TEXTURE_MAG_FILTER: |
||
730 | case GL_TEXTURE_WRAP_S: |
||
731 | case GL_TEXTURE_WRAP_T: |
||
732 | case GL_TEXTURE_WRAP_R: |
||
733 | case GL_TEXTURE_BASE_LEVEL: |
||
734 | case GL_TEXTURE_MAX_LEVEL: |
||
735 | case GL_GENERATE_MIPMAP_SGIS: |
||
736 | case GL_TEXTURE_COMPARE_MODE_ARB: |
||
737 | case GL_TEXTURE_COMPARE_FUNC_ARB: |
||
738 | case GL_DEPTH_TEXTURE_MODE_ARB: |
||
739 | case GL_TEXTURE_SRGB_DECODE_EXT: |
||
740 | case GL_TEXTURE_CUBE_MAP_SEAMLESS: |
||
741 | case GL_TEXTURE_SWIZZLE_R_EXT: |
||
742 | case GL_TEXTURE_SWIZZLE_G_EXT: |
||
743 | case GL_TEXTURE_SWIZZLE_B_EXT: |
||
744 | case GL_TEXTURE_SWIZZLE_A_EXT: |
||
745 | { |
||
746 | GLint p[4]; |
||
747 | p[0] = (param > 0) ? |
||
748 | ((param > INT_MAX) ? INT_MAX : (GLint) (param + 0.5)) : |
||
749 | ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5)); |
||
750 | |||
751 | p[1] = p[2] = p[3] = 0; |
||
752 | need_update = set_tex_parameteri(ctx, texObj, pname, p); |
||
753 | } |
||
754 | break; |
||
755 | default: |
||
756 | { |
||
757 | /* this will generate an error if pname is illegal */ |
||
758 | GLfloat p[4]; |
||
759 | p[0] = param; |
||
760 | p[1] = p[2] = p[3] = 0.0F; |
||
761 | need_update = set_tex_parameterf(ctx, texObj, pname, p); |
||
762 | } |
||
763 | } |
||
764 | |||
765 | if (ctx->Driver.TexParameter && need_update) { |
||
766 | ctx->Driver.TexParameter(ctx, target, texObj, pname, ¶m); |
||
767 | } |
||
768 | } |
||
769 | |||
770 | |||
771 | void GLAPIENTRY |
||
772 | _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) |
||
773 | { |
||
774 | GLboolean need_update; |
||
775 | struct gl_texture_object *texObj; |
||
776 | GET_CURRENT_CONTEXT(ctx); |
||
777 | |||
778 | texObj = get_texobj(ctx, target, GL_FALSE); |
||
779 | if (!texObj) |
||
780 | return; |
||
781 | |||
782 | switch (pname) { |
||
783 | case GL_TEXTURE_MIN_FILTER: |
||
784 | case GL_TEXTURE_MAG_FILTER: |
||
785 | case GL_TEXTURE_WRAP_S: |
||
786 | case GL_TEXTURE_WRAP_T: |
||
787 | case GL_TEXTURE_WRAP_R: |
||
788 | case GL_TEXTURE_BASE_LEVEL: |
||
789 | case GL_TEXTURE_MAX_LEVEL: |
||
790 | case GL_GENERATE_MIPMAP_SGIS: |
||
791 | case GL_TEXTURE_COMPARE_MODE_ARB: |
||
792 | case GL_TEXTURE_COMPARE_FUNC_ARB: |
||
793 | case GL_DEPTH_TEXTURE_MODE_ARB: |
||
794 | case GL_TEXTURE_SRGB_DECODE_EXT: |
||
795 | case GL_TEXTURE_CUBE_MAP_SEAMLESS: |
||
796 | { |
||
797 | /* convert float param to int */ |
||
798 | GLint p[4]; |
||
799 | p[0] = (GLint) params[0]; |
||
800 | p[1] = p[2] = p[3] = 0; |
||
801 | need_update = set_tex_parameteri(ctx, texObj, pname, p); |
||
802 | } |
||
803 | break; |
||
804 | case GL_TEXTURE_CROP_RECT_OES: |
||
805 | { |
||
806 | /* convert float params to int */ |
||
807 | GLint iparams[4]; |
||
808 | iparams[0] = (GLint) params[0]; |
||
809 | iparams[1] = (GLint) params[1]; |
||
810 | iparams[2] = (GLint) params[2]; |
||
811 | iparams[3] = (GLint) params[3]; |
||
812 | need_update = set_tex_parameteri(ctx, texObj, pname, iparams); |
||
813 | } |
||
814 | break; |
||
815 | case GL_TEXTURE_SWIZZLE_R_EXT: |
||
816 | case GL_TEXTURE_SWIZZLE_G_EXT: |
||
817 | case GL_TEXTURE_SWIZZLE_B_EXT: |
||
818 | case GL_TEXTURE_SWIZZLE_A_EXT: |
||
819 | case GL_TEXTURE_SWIZZLE_RGBA_EXT: |
||
820 | { |
||
821 | GLint p[4] = {0, 0, 0, 0}; |
||
822 | p[0] = (GLint) params[0]; |
||
823 | if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT) { |
||
824 | p[1] = (GLint) params[1]; |
||
825 | p[2] = (GLint) params[2]; |
||
826 | p[3] = (GLint) params[3]; |
||
827 | } |
||
828 | need_update = set_tex_parameteri(ctx, texObj, pname, p); |
||
829 | } |
||
830 | break; |
||
831 | default: |
||
832 | /* this will generate an error if pname is illegal */ |
||
833 | need_update = set_tex_parameterf(ctx, texObj, pname, params); |
||
834 | } |
||
835 | |||
836 | if (ctx->Driver.TexParameter && need_update) { |
||
837 | ctx->Driver.TexParameter(ctx, target, texObj, pname, params); |
||
838 | } |
||
839 | } |
||
840 | |||
841 | |||
842 | void GLAPIENTRY |
||
843 | _mesa_TexParameteri(GLenum target, GLenum pname, GLint param) |
||
844 | { |
||
845 | GLboolean need_update; |
||
846 | struct gl_texture_object *texObj; |
||
847 | GET_CURRENT_CONTEXT(ctx); |
||
848 | |||
849 | texObj = get_texobj(ctx, target, GL_FALSE); |
||
850 | if (!texObj) |
||
851 | return; |
||
852 | |||
853 | switch (pname) { |
||
854 | case GL_TEXTURE_MIN_LOD: |
||
855 | case GL_TEXTURE_MAX_LOD: |
||
856 | case GL_TEXTURE_PRIORITY: |
||
857 | case GL_TEXTURE_MAX_ANISOTROPY_EXT: |
||
858 | case GL_TEXTURE_LOD_BIAS: |
||
859 | case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: |
||
860 | { |
||
861 | GLfloat fparam[4]; |
||
862 | fparam[0] = (GLfloat) param; |
||
863 | fparam[1] = fparam[2] = fparam[3] = 0.0F; |
||
864 | /* convert int param to float */ |
||
865 | need_update = set_tex_parameterf(ctx, texObj, pname, fparam); |
||
866 | } |
||
867 | break; |
||
868 | default: |
||
869 | /* this will generate an error if pname is illegal */ |
||
870 | { |
||
871 | GLint iparam[4]; |
||
872 | iparam[0] = param; |
||
873 | iparam[1] = iparam[2] = iparam[3] = 0; |
||
874 | need_update = set_tex_parameteri(ctx, texObj, pname, iparam); |
||
875 | } |
||
876 | } |
||
877 | |||
878 | if (ctx->Driver.TexParameter && need_update) { |
||
879 | GLfloat fparam = (GLfloat) param; |
||
880 | ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam); |
||
881 | } |
||
882 | } |
||
883 | |||
884 | |||
885 | void GLAPIENTRY |
||
886 | _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) |
||
887 | { |
||
888 | GLboolean need_update; |
||
889 | struct gl_texture_object *texObj; |
||
890 | GET_CURRENT_CONTEXT(ctx); |
||
891 | |||
892 | texObj = get_texobj(ctx, target, GL_FALSE); |
||
893 | if (!texObj) |
||
894 | return; |
||
895 | |||
896 | switch (pname) { |
||
897 | case GL_TEXTURE_BORDER_COLOR: |
||
898 | { |
||
899 | /* convert int params to float */ |
||
900 | GLfloat fparams[4]; |
||
901 | fparams[0] = INT_TO_FLOAT(params[0]); |
||
902 | fparams[1] = INT_TO_FLOAT(params[1]); |
||
903 | fparams[2] = INT_TO_FLOAT(params[2]); |
||
904 | fparams[3] = INT_TO_FLOAT(params[3]); |
||
905 | need_update = set_tex_parameterf(ctx, texObj, pname, fparams); |
||
906 | } |
||
907 | break; |
||
908 | case GL_TEXTURE_MIN_LOD: |
||
909 | case GL_TEXTURE_MAX_LOD: |
||
910 | case GL_TEXTURE_PRIORITY: |
||
911 | case GL_TEXTURE_MAX_ANISOTROPY_EXT: |
||
912 | case GL_TEXTURE_LOD_BIAS: |
||
913 | case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: |
||
914 | { |
||
915 | /* convert int param to float */ |
||
916 | GLfloat fparams[4]; |
||
917 | fparams[0] = (GLfloat) params[0]; |
||
918 | fparams[1] = fparams[2] = fparams[3] = 0.0F; |
||
919 | need_update = set_tex_parameterf(ctx, texObj, pname, fparams); |
||
920 | } |
||
921 | break; |
||
922 | default: |
||
923 | /* this will generate an error if pname is illegal */ |
||
924 | need_update = set_tex_parameteri(ctx, texObj, pname, params); |
||
925 | } |
||
926 | |||
927 | if (ctx->Driver.TexParameter && need_update) { |
||
928 | GLfloat fparams[4]; |
||
929 | fparams[0] = INT_TO_FLOAT(params[0]); |
||
930 | if (pname == GL_TEXTURE_BORDER_COLOR || |
||
931 | pname == GL_TEXTURE_CROP_RECT_OES) { |
||
932 | fparams[1] = INT_TO_FLOAT(params[1]); |
||
933 | fparams[2] = INT_TO_FLOAT(params[2]); |
||
934 | fparams[3] = INT_TO_FLOAT(params[3]); |
||
935 | } |
||
936 | ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams); |
||
937 | } |
||
938 | } |
||
939 | |||
940 | |||
941 | /** |
||
942 | * Set tex parameter to integer value(s). Primarily intended to set |
||
943 | * integer-valued texture border color (for integer-valued textures). |
||
944 | * New in GL 3.0. |
||
945 | */ |
||
946 | void GLAPIENTRY |
||
947 | _mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params) |
||
948 | { |
||
949 | struct gl_texture_object *texObj; |
||
950 | GET_CURRENT_CONTEXT(ctx); |
||
951 | |||
952 | texObj = get_texobj(ctx, target, GL_FALSE); |
||
953 | if (!texObj) |
||
954 | return; |
||
955 | |||
956 | switch (pname) { |
||
957 | case GL_TEXTURE_BORDER_COLOR: |
||
958 | FLUSH_VERTICES(ctx, _NEW_TEXTURE); |
||
959 | /* set the integer-valued border color */ |
||
960 | COPY_4V(texObj->Sampler.BorderColor.i, params); |
||
961 | break; |
||
962 | default: |
||
963 | _mesa_TexParameteriv(target, pname, params); |
||
964 | break; |
||
965 | } |
||
966 | /* XXX no driver hook for TexParameterIiv() yet */ |
||
967 | } |
||
968 | |||
969 | |||
970 | /** |
||
971 | * Set tex parameter to unsigned integer value(s). Primarily intended to set |
||
972 | * uint-valued texture border color (for integer-valued textures). |
||
973 | * New in GL 3.0 |
||
974 | */ |
||
975 | void GLAPIENTRY |
||
976 | _mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params) |
||
977 | { |
||
978 | struct gl_texture_object *texObj; |
||
979 | GET_CURRENT_CONTEXT(ctx); |
||
980 | |||
981 | texObj = get_texobj(ctx, target, GL_FALSE); |
||
982 | if (!texObj) |
||
983 | return; |
||
984 | |||
985 | switch (pname) { |
||
986 | case GL_TEXTURE_BORDER_COLOR: |
||
987 | FLUSH_VERTICES(ctx, _NEW_TEXTURE); |
||
988 | /* set the unsigned integer-valued border color */ |
||
989 | COPY_4V(texObj->Sampler.BorderColor.ui, params); |
||
990 | break; |
||
991 | default: |
||
992 | _mesa_TexParameteriv(target, pname, (const GLint *) params); |
||
993 | break; |
||
994 | } |
||
995 | /* XXX no driver hook for TexParameterIuiv() yet */ |
||
996 | } |
||
997 | |||
998 | |||
999 | static GLboolean |
||
1000 | legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target) |
||
1001 | { |
||
1002 | switch (target) { |
||
1003 | case GL_TEXTURE_1D: |
||
1004 | case GL_PROXY_TEXTURE_1D: |
||
1005 | case GL_TEXTURE_2D: |
||
1006 | case GL_PROXY_TEXTURE_2D: |
||
1007 | case GL_TEXTURE_3D: |
||
1008 | case GL_PROXY_TEXTURE_3D: |
||
1009 | return GL_TRUE; |
||
1010 | case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: |
||
1011 | case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: |
||
1012 | case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: |
||
1013 | case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: |
||
1014 | case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: |
||
1015 | case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: |
||
1016 | case GL_PROXY_TEXTURE_CUBE_MAP_ARB: |
||
1017 | return ctx->Extensions.ARB_texture_cube_map; |
||
1018 | case GL_TEXTURE_RECTANGLE_NV: |
||
1019 | case GL_PROXY_TEXTURE_RECTANGLE_NV: |
||
1020 | return ctx->Extensions.NV_texture_rectangle; |
||
1021 | case GL_TEXTURE_1D_ARRAY_EXT: |
||
1022 | case GL_PROXY_TEXTURE_1D_ARRAY_EXT: |
||
1023 | case GL_TEXTURE_2D_ARRAY_EXT: |
||
1024 | case GL_PROXY_TEXTURE_2D_ARRAY_EXT: |
||
1025 | return (ctx->Extensions.MESA_texture_array || |
||
1026 | ctx->Extensions.EXT_texture_array); |
||
1027 | case GL_TEXTURE_BUFFER: |
||
1028 | /* GetTexLevelParameter accepts GL_TEXTURE_BUFFER in GL 3.1+ contexts, |
||
1029 | * but not in earlier versions that expose ARB_texture_buffer_object. |
||
1030 | * |
||
1031 | * From the ARB_texture_buffer_object spec: |
||
1032 | * "(7) Do buffer textures support texture parameters (TexParameter) or |
||
1033 | * queries (GetTexParameter, GetTexLevelParameter, GetTexImage)? |
||
1034 | * |
||
1035 | * RESOLVED: No. [...] Note that the spec edits above don't add |
||
1036 | * explicit error language for any of these cases. That is because |
||
1037 | * each of the functions enumerate the set of valid |
||
1038 | * parameters. Not editing the spec to allow TEXTURE_BUFFER_ARB in |
||
1039 | * these cases means that target is not legal, and an INVALID_ENUM |
||
1040 | * error should be generated." |
||
1041 | * |
||
1042 | * From the OpenGL 3.1 spec: |
||
1043 | * "target may also be TEXTURE_BUFFER, indicating the texture buffer." |
||
1044 | */ |
||
1045 | return ctx->API == API_OPENGL_CORE && ctx->Version >= 31; |
||
1046 | case GL_TEXTURE_2D_MULTISAMPLE: |
||
1047 | case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: |
||
1048 | case GL_PROXY_TEXTURE_2D_MULTISAMPLE: |
||
1049 | case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: |
||
1050 | return ctx->Extensions.ARB_texture_multisample; |
||
1051 | default: |
||
1052 | return GL_FALSE; |
||
1053 | } |
||
1054 | } |
||
1055 | |||
1056 | |||
1057 | static void |
||
1058 | get_tex_level_parameter_image(struct gl_context *ctx, |
||
1059 | const struct gl_texture_object *texObj, |
||
1060 | GLenum target, GLint level, |
||
1061 | GLenum pname, GLint *params) |
||
1062 | { |
||
1063 | const struct gl_texture_image *img = NULL; |
||
1064 | gl_format texFormat; |
||
1065 | |||
1066 | img = _mesa_select_tex_image(ctx, texObj, target, level); |
||
1067 | if (!img || img->TexFormat == MESA_FORMAT_NONE) { |
||
1068 | /* undefined texture image */ |
||
1069 | if (pname == GL_TEXTURE_COMPONENTS) |
||
1070 | *params = 1; |
||
1071 | else |
||
1072 | *params = 0; |
||
1073 | return; |
||
1074 | } |
||
1075 | |||
1076 | texFormat = img->TexFormat; |
||
1077 | |||
1078 | switch (pname) { |
||
1079 | case GL_TEXTURE_WIDTH: |
||
1080 | *params = img->Width; |
||
1081 | break; |
||
1082 | case GL_TEXTURE_HEIGHT: |
||
1083 | *params = img->Height; |
||
1084 | break; |
||
1085 | case GL_TEXTURE_DEPTH: |
||
1086 | *params = img->Depth; |
||
1087 | break; |
||
1088 | case GL_TEXTURE_INTERNAL_FORMAT: |
||
1089 | if (_mesa_is_format_compressed(texFormat)) { |
||
1090 | /* need to return the actual compressed format */ |
||
1091 | *params = _mesa_compressed_format_to_glenum(ctx, texFormat); |
||
1092 | } |
||
1093 | else { |
||
1094 | /* If the true internal format is not compressed but the user |
||
1095 | * requested a generic compressed format, we have to return the |
||
1096 | * generic base format that matches. |
||
1097 | * |
||
1098 | * From page 119 (page 129 of the PDF) of the OpenGL 1.3 spec: |
||
1099 | * |
||
1100 | * "If no specific compressed format is available, |
||
1101 | * internalformat is instead replaced by the corresponding base |
||
1102 | * internal format." |
||
1103 | * |
||
1104 | * Otherwise just return the user's requested internal format |
||
1105 | */ |
||
1106 | const GLenum f = |
||
1107 | _mesa_gl_compressed_format_base_format(img->InternalFormat); |
||
1108 | |||
1109 | *params = (f != 0) ? f : img->InternalFormat; |
||
1110 | } |
||
1111 | break; |
||
1112 | case GL_TEXTURE_BORDER: |
||
1113 | *params = img->Border; |
||
1114 | break; |
||
1115 | case GL_TEXTURE_RED_SIZE: |
||
1116 | case GL_TEXTURE_GREEN_SIZE: |
||
1117 | case GL_TEXTURE_BLUE_SIZE: |
||
1118 | case GL_TEXTURE_ALPHA_SIZE: |
||
1119 | if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) |
||
1120 | *params = _mesa_get_format_bits(texFormat, pname); |
||
1121 | else |
||
1122 | *params = 0; |
||
1123 | break; |
||
1124 | case GL_TEXTURE_INTENSITY_SIZE: |
||
1125 | case GL_TEXTURE_LUMINANCE_SIZE: |
||
1126 | if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) { |
||
1127 | *params = _mesa_get_format_bits(texFormat, pname); |
||
1128 | if (*params == 0) { |
||
1129 | /* intensity or luminance is probably stored as RGB[A] */ |
||
1130 | *params = MIN2(_mesa_get_format_bits(texFormat, |
||
1131 | GL_TEXTURE_RED_SIZE), |
||
1132 | _mesa_get_format_bits(texFormat, |
||
1133 | GL_TEXTURE_GREEN_SIZE)); |
||
1134 | } |
||
1135 | } |
||
1136 | else { |
||
1137 | *params = 0; |
||
1138 | } |
||
1139 | break; |
||
1140 | case GL_TEXTURE_DEPTH_SIZE_ARB: |
||
1141 | if (!ctx->Extensions.ARB_depth_texture) |
||
1142 | goto invalid_pname; |
||
1143 | *params = _mesa_get_format_bits(texFormat, pname); |
||
1144 | break; |
||
1145 | case GL_TEXTURE_STENCIL_SIZE_EXT: |
||
1146 | if (!ctx->Extensions.EXT_packed_depth_stencil && |
||
1147 | !ctx->Extensions.ARB_framebuffer_object) |
||
1148 | goto invalid_pname; |
||
1149 | *params = _mesa_get_format_bits(texFormat, pname); |
||
1150 | break; |
||
1151 | case GL_TEXTURE_SHARED_SIZE: |
||
1152 | if (ctx->Version < 30 && |
||
1153 | !ctx->Extensions.EXT_texture_shared_exponent) |
||
1154 | goto invalid_pname; |
||
1155 | *params = texFormat == MESA_FORMAT_RGB9_E5_FLOAT ? 5 : 0; |
||
1156 | break; |
||
1157 | |||
1158 | /* GL_ARB_texture_compression */ |
||
1159 | case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: |
||
1160 | if (_mesa_is_format_compressed(texFormat) && |
||
1161 | !_mesa_is_proxy_texture(target)) { |
||
1162 | *params = _mesa_format_image_size(texFormat, img->Width, |
||
1163 | img->Height, img->Depth); |
||
1164 | } |
||
1165 | else { |
||
1166 | _mesa_error(ctx, GL_INVALID_OPERATION, |
||
1167 | "glGetTexLevelParameter[if]v(pname)"); |
||
1168 | } |
||
1169 | break; |
||
1170 | case GL_TEXTURE_COMPRESSED: |
||
1171 | *params = (GLint) _mesa_is_format_compressed(texFormat); |
||
1172 | break; |
||
1173 | |||
1174 | /* GL_ARB_texture_float */ |
||
1175 | case GL_TEXTURE_RED_TYPE_ARB: |
||
1176 | case GL_TEXTURE_GREEN_TYPE_ARB: |
||
1177 | case GL_TEXTURE_BLUE_TYPE_ARB: |
||
1178 | case GL_TEXTURE_ALPHA_TYPE_ARB: |
||
1179 | case GL_TEXTURE_LUMINANCE_TYPE_ARB: |
||
1180 | case GL_TEXTURE_INTENSITY_TYPE_ARB: |
||
1181 | case GL_TEXTURE_DEPTH_TYPE_ARB: |
||
1182 | if (!ctx->Extensions.ARB_texture_float) |
||
1183 | goto invalid_pname; |
||
1184 | if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) |
||
1185 | *params = _mesa_get_format_datatype(texFormat); |
||
1186 | else |
||
1187 | *params = GL_NONE; |
||
1188 | break; |
||
1189 | |||
1190 | /* GL_ARB_texture_multisample */ |
||
1191 | case GL_TEXTURE_SAMPLES: |
||
1192 | if (!ctx->Extensions.ARB_texture_multisample) |
||
1193 | goto invalid_pname; |
||
1194 | *params = img->NumSamples; |
||
1195 | break; |
||
1196 | |||
1197 | case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: |
||
1198 | if (!ctx->Extensions.ARB_texture_multisample) |
||
1199 | goto invalid_pname; |
||
1200 | *params = img->FixedSampleLocations; |
||
1201 | break; |
||
1202 | |||
1203 | default: |
||
1204 | goto invalid_pname; |
||
1205 | } |
||
1206 | |||
1207 | /* no error if we get here */ |
||
1208 | return; |
||
1209 | |||
1210 | invalid_pname: |
||
1211 | _mesa_error(ctx, GL_INVALID_ENUM, |
||
1212 | "glGetTexLevelParameter[if]v(pname=%s)", |
||
1213 | _mesa_lookup_enum_by_nr(pname)); |
||
1214 | } |
||
1215 | |||
1216 | |||
1217 | static void |
||
1218 | get_tex_level_parameter_buffer(struct gl_context *ctx, |
||
1219 | const struct gl_texture_object *texObj, |
||
1220 | GLenum pname, GLint *params) |
||
1221 | { |
||
1222 | const struct gl_buffer_object *bo = texObj->BufferObject; |
||
1223 | gl_format texFormat = texObj->_BufferObjectFormat; |
||
1224 | GLenum internalFormat = texObj->BufferObjectFormat; |
||
1225 | GLenum baseFormat = _mesa_get_format_base_format(texFormat); |
||
1226 | |||
1227 | if (!bo) { |
||
1228 | /* undefined texture buffer object */ |
||
1229 | *params = pname == GL_TEXTURE_COMPONENTS ? 1 : 0; |
||
1230 | return; |
||
1231 | } |
||
1232 | |||
1233 | switch (pname) { |
||
1234 | case GL_TEXTURE_BUFFER_DATA_STORE_BINDING: |
||
1235 | *params = bo->Name; |
||
1236 | break; |
||
1237 | case GL_TEXTURE_WIDTH: |
||
1238 | *params = bo->Size; |
||
1239 | break; |
||
1240 | case GL_TEXTURE_HEIGHT: |
||
1241 | case GL_TEXTURE_DEPTH: |
||
1242 | case GL_TEXTURE_BORDER: |
||
1243 | case GL_TEXTURE_SHARED_SIZE: |
||
1244 | case GL_TEXTURE_COMPRESSED: |
||
1245 | *params = 0; |
||
1246 | break; |
||
1247 | case GL_TEXTURE_INTERNAL_FORMAT: |
||
1248 | *params = internalFormat; |
||
1249 | break; |
||
1250 | case GL_TEXTURE_RED_SIZE: |
||
1251 | case GL_TEXTURE_GREEN_SIZE: |
||
1252 | case GL_TEXTURE_BLUE_SIZE: |
||
1253 | case GL_TEXTURE_ALPHA_SIZE: |
||
1254 | if (_mesa_base_format_has_channel(baseFormat, pname)) |
||
1255 | *params = _mesa_get_format_bits(texFormat, pname); |
||
1256 | else |
||
1257 | *params = 0; |
||
1258 | break; |
||
1259 | case GL_TEXTURE_INTENSITY_SIZE: |
||
1260 | case GL_TEXTURE_LUMINANCE_SIZE: |
||
1261 | if (_mesa_base_format_has_channel(baseFormat, pname)) { |
||
1262 | *params = _mesa_get_format_bits(texFormat, pname); |
||
1263 | if (*params == 0) { |
||
1264 | /* intensity or luminance is probably stored as RGB[A] */ |
||
1265 | *params = MIN2(_mesa_get_format_bits(texFormat, |
||
1266 | GL_TEXTURE_RED_SIZE), |
||
1267 | _mesa_get_format_bits(texFormat, |
||
1268 | GL_TEXTURE_GREEN_SIZE)); |
||
1269 | } |
||
1270 | } else { |
||
1271 | *params = 0; |
||
1272 | } |
||
1273 | break; |
||
1274 | case GL_TEXTURE_DEPTH_SIZE_ARB: |
||
1275 | case GL_TEXTURE_STENCIL_SIZE_EXT: |
||
1276 | *params = _mesa_get_format_bits(texFormat, pname); |
||
1277 | break; |
||
1278 | |||
1279 | /* GL_ARB_texture_buffer_range */ |
||
1280 | case GL_TEXTURE_BUFFER_OFFSET: |
||
1281 | if (!ctx->Extensions.ARB_texture_buffer_range) |
||
1282 | goto invalid_pname; |
||
1283 | *params = texObj->BufferOffset; |
||
1284 | break; |
||
1285 | case GL_TEXTURE_BUFFER_SIZE: |
||
1286 | if (!ctx->Extensions.ARB_texture_buffer_range) |
||
1287 | goto invalid_pname; |
||
1288 | *params = (texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize; |
||
1289 | break; |
||
1290 | |||
1291 | /* GL_ARB_texture_compression */ |
||
1292 | case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: |
||
1293 | /* Always illegal for GL_TEXTURE_BUFFER */ |
||
1294 | _mesa_error(ctx, GL_INVALID_OPERATION, |
||
1295 | "glGetTexLevelParameter[if]v(pname)"); |
||
1296 | break; |
||
1297 | |||
1298 | /* GL_ARB_texture_float */ |
||
1299 | case GL_TEXTURE_RED_TYPE_ARB: |
||
1300 | case GL_TEXTURE_GREEN_TYPE_ARB: |
||
1301 | case GL_TEXTURE_BLUE_TYPE_ARB: |
||
1302 | case GL_TEXTURE_ALPHA_TYPE_ARB: |
||
1303 | case GL_TEXTURE_LUMINANCE_TYPE_ARB: |
||
1304 | case GL_TEXTURE_INTENSITY_TYPE_ARB: |
||
1305 | case GL_TEXTURE_DEPTH_TYPE_ARB: |
||
1306 | if (!ctx->Extensions.ARB_texture_float) |
||
1307 | goto invalid_pname; |
||
1308 | if (_mesa_base_format_has_channel(baseFormat, pname)) |
||
1309 | *params = _mesa_get_format_datatype(texFormat); |
||
1310 | else |
||
1311 | *params = GL_NONE; |
||
1312 | break; |
||
1313 | |||
1314 | default: |
||
1315 | goto invalid_pname; |
||
1316 | } |
||
1317 | |||
1318 | /* no error if we get here */ |
||
1319 | return; |
||
1320 | |||
1321 | invalid_pname: |
||
1322 | _mesa_error(ctx, GL_INVALID_ENUM, |
||
1323 | "glGetTexLevelParameter[if]v(pname=%s)", |
||
1324 | _mesa_lookup_enum_by_nr(pname)); |
||
1325 | } |
||
1326 | |||
1327 | |||
1328 | void GLAPIENTRY |
||
1329 | _mesa_GetTexLevelParameterfv( GLenum target, GLint level, |
||
1330 | GLenum pname, GLfloat *params ) |
||
1331 | { |
||
1332 | GLint iparam; |
||
1333 | _mesa_GetTexLevelParameteriv( target, level, pname, &iparam ); |
||
1334 | *params = (GLfloat) iparam; |
||
1335 | } |
||
1336 | |||
1337 | |||
1338 | void GLAPIENTRY |
||
1339 | _mesa_GetTexLevelParameteriv( GLenum target, GLint level, |
||
1340 | GLenum pname, GLint *params ) |
||
1341 | { |
||
1342 | const struct gl_texture_unit *texUnit; |
||
1343 | struct gl_texture_object *texObj; |
||
1344 | GLint maxLevels; |
||
1345 | GET_CURRENT_CONTEXT(ctx); |
||
1346 | |||
1347 | if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) { |
||
1348 | _mesa_error(ctx, GL_INVALID_OPERATION, |
||
1349 | "glGetTexLevelParameteriv(current unit)"); |
||
1350 | return; |
||
1351 | } |
||
1352 | |||
1353 | texUnit = _mesa_get_current_tex_unit(ctx); |
||
1354 | |||
1355 | if (!legal_get_tex_level_parameter_target(ctx, target)) { |
||
1356 | _mesa_error(ctx, GL_INVALID_ENUM, |
||
1357 | "glGetTexLevelParameter[if]v(target=0x%x)", target); |
||
1358 | return; |
||
1359 | } |
||
1360 | |||
1361 | maxLevels = _mesa_max_texture_levels(ctx, target); |
||
1362 | assert(maxLevels != 0); |
||
1363 | |||
1364 | if (level < 0 || level >= maxLevels) { |
||
1365 | _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" ); |
||
1366 | return; |
||
1367 | } |
||
1368 | |||
1369 | texObj = _mesa_select_tex_object(ctx, texUnit, target); |
||
1370 | |||
1371 | if (target == GL_TEXTURE_BUFFER) |
||
1372 | get_tex_level_parameter_buffer(ctx, texObj, pname, params); |
||
1373 | else |
||
1374 | get_tex_level_parameter_image(ctx, texObj, target, level, pname, params); |
||
1375 | } |
||
1376 | |||
1377 | |||
1378 | void GLAPIENTRY |
||
1379 | _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) |
||
1380 | { |
||
1381 | struct gl_texture_object *obj; |
||
1382 | GET_CURRENT_CONTEXT(ctx); |
||
1383 | |||
1384 | obj = get_texobj(ctx, target, GL_TRUE); |
||
1385 | if (!obj) |
||
1386 | return; |
||
1387 | |||
1388 | _mesa_lock_texture(ctx, obj); |
||
1389 | switch (pname) { |
||
1390 | case GL_TEXTURE_MAG_FILTER: |
||
1391 | *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter); |
||
1392 | break; |
||
1393 | case GL_TEXTURE_MIN_FILTER: |
||
1394 | *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter); |
||
1395 | break; |
||
1396 | case GL_TEXTURE_WRAP_S: |
||
1397 | *params = ENUM_TO_FLOAT(obj->Sampler.WrapS); |
||
1398 | break; |
||
1399 | case GL_TEXTURE_WRAP_T: |
||
1400 | *params = ENUM_TO_FLOAT(obj->Sampler.WrapT); |
||
1401 | break; |
||
1402 | case GL_TEXTURE_WRAP_R: |
||
1403 | *params = ENUM_TO_FLOAT(obj->Sampler.WrapR); |
||
1404 | break; |
||
1405 | case GL_TEXTURE_BORDER_COLOR: |
||
1406 | if (!_mesa_is_desktop_gl(ctx)) |
||
1407 | goto invalid_pname; |
||
1408 | |||
1409 | if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP)) |
||
1410 | _mesa_update_state_locked(ctx); |
||
1411 | if (_mesa_get_clamp_fragment_color(ctx)) { |
||
1412 | params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F); |
||
1413 | params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F); |
||
1414 | params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F); |
||
1415 | params[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F); |
||
1416 | } |
||
1417 | else { |
||
1418 | params[0] = obj->Sampler.BorderColor.f[0]; |
||
1419 | params[1] = obj->Sampler.BorderColor.f[1]; |
||
1420 | params[2] = obj->Sampler.BorderColor.f[2]; |
||
1421 | params[3] = obj->Sampler.BorderColor.f[3]; |
||
1422 | } |
||
1423 | break; |
||
1424 | case GL_TEXTURE_RESIDENT: |
||
1425 | if (ctx->API != API_OPENGL_COMPAT) |
||
1426 | goto invalid_pname; |
||
1427 | |||
1428 | *params = 1.0F; |
||
1429 | break; |
||
1430 | case GL_TEXTURE_PRIORITY: |
||
1431 | if (ctx->API != API_OPENGL_COMPAT) |
||
1432 | goto invalid_pname; |
||
1433 | |||
1434 | *params = obj->Priority; |
||
1435 | break; |
||
1436 | case GL_TEXTURE_MIN_LOD: |
||
1437 | if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) |
||
1438 | goto invalid_pname; |
||
1439 | |||
1440 | *params = obj->Sampler.MinLod; |
||
1441 | break; |
||
1442 | case GL_TEXTURE_MAX_LOD: |
||
1443 | if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) |
||
1444 | goto invalid_pname; |
||
1445 | |||
1446 | *params = obj->Sampler.MaxLod; |
||
1447 | break; |
||
1448 | case GL_TEXTURE_BASE_LEVEL: |
||
1449 | if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) |
||
1450 | goto invalid_pname; |
||
1451 | |||
1452 | *params = (GLfloat) obj->BaseLevel; |
||
1453 | break; |
||
1454 | case GL_TEXTURE_MAX_LEVEL: |
||
1455 | *params = (GLfloat) obj->MaxLevel; |
||
1456 | break; |
||
1457 | case GL_TEXTURE_MAX_ANISOTROPY_EXT: |
||
1458 | if (!ctx->Extensions.EXT_texture_filter_anisotropic) |
||
1459 | goto invalid_pname; |
||
1460 | *params = obj->Sampler.MaxAnisotropy; |
||
1461 | break; |
||
1462 | case GL_GENERATE_MIPMAP_SGIS: |
||
1463 | if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) |
||
1464 | goto invalid_pname; |
||
1465 | |||
1466 | *params = (GLfloat) obj->GenerateMipmap; |
||
1467 | break; |
||
1468 | case GL_TEXTURE_COMPARE_MODE_ARB: |
||
1469 | if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) |
||
1470 | && !_mesa_is_gles3(ctx)) |
||
1471 | goto invalid_pname; |
||
1472 | *params = (GLfloat) obj->Sampler.CompareMode; |
||
1473 | break; |
||
1474 | case GL_TEXTURE_COMPARE_FUNC_ARB: |
||
1475 | if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) |
||
1476 | && !_mesa_is_gles3(ctx)) |
||
1477 | goto invalid_pname; |
||
1478 | *params = (GLfloat) obj->Sampler.CompareFunc; |
||
1479 | break; |
||
1480 | case GL_DEPTH_TEXTURE_MODE_ARB: |
||
1481 | /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has |
||
1482 | * never existed in OpenGL ES. |
||
1483 | */ |
||
1484 | if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture) |
||
1485 | goto invalid_pname; |
||
1486 | *params = (GLfloat) obj->DepthMode; |
||
1487 | break; |
||
1488 | case GL_TEXTURE_LOD_BIAS: |
||
4401 | Serge | 1489 | if (_mesa_is_gles(ctx)) |
4358 | Serge | 1490 | goto invalid_pname; |
1491 | |||
1492 | *params = obj->Sampler.LodBias; |
||
1493 | break; |
||
1494 | case GL_TEXTURE_CROP_RECT_OES: |
||
1495 | if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture) |
||
1496 | goto invalid_pname; |
||
1497 | |||
1498 | params[0] = (GLfloat) obj->CropRect[0]; |
||
1499 | params[1] = (GLfloat) obj->CropRect[1]; |
||
1500 | params[2] = (GLfloat) obj->CropRect[2]; |
||
1501 | params[3] = (GLfloat) obj->CropRect[3]; |
||
1502 | break; |
||
1503 | |||
1504 | case GL_TEXTURE_SWIZZLE_R_EXT: |
||
1505 | case GL_TEXTURE_SWIZZLE_G_EXT: |
||
1506 | case GL_TEXTURE_SWIZZLE_B_EXT: |
||
1507 | case GL_TEXTURE_SWIZZLE_A_EXT: |
||
1508 | if ((!_mesa_is_desktop_gl(ctx) |
||
1509 | || !ctx->Extensions.EXT_texture_swizzle) |
||
1510 | && !_mesa_is_gles3(ctx)) |
||
1511 | goto invalid_pname; |
||
1512 | *params = (GLfloat) obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT]; |
||
1513 | break; |
||
1514 | |||
1515 | case GL_TEXTURE_SWIZZLE_RGBA_EXT: |
||
1516 | if ((!_mesa_is_desktop_gl(ctx) |
||
1517 | || !ctx->Extensions.EXT_texture_swizzle) |
||
1518 | && !_mesa_is_gles3(ctx)) { |
||
1519 | goto invalid_pname; |
||
1520 | } |
||
1521 | else { |
||
1522 | GLuint comp; |
||
1523 | for (comp = 0; comp < 4; comp++) { |
||
1524 | params[comp] = (GLfloat) obj->Swizzle[comp]; |
||
1525 | } |
||
1526 | } |
||
1527 | break; |
||
1528 | |||
1529 | case GL_TEXTURE_CUBE_MAP_SEAMLESS: |
||
1530 | if (!_mesa_is_desktop_gl(ctx) |
||
1531 | || !ctx->Extensions.AMD_seamless_cubemap_per_texture) |
||
1532 | goto invalid_pname; |
||
1533 | *params = (GLfloat) obj->Sampler.CubeMapSeamless; |
||
1534 | break; |
||
1535 | |||
1536 | case GL_TEXTURE_IMMUTABLE_FORMAT: |
||
1537 | *params = (GLfloat) obj->Immutable; |
||
1538 | break; |
||
1539 | |||
1540 | case GL_TEXTURE_IMMUTABLE_LEVELS: |
||
1541 | if (!_mesa_is_gles3(ctx)) |
||
1542 | goto invalid_pname; |
||
1543 | *params = (GLfloat) obj->ImmutableLevels; |
||
1544 | break; |
||
1545 | |||
1546 | case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: |
||
1547 | if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external) |
||
1548 | goto invalid_pname; |
||
1549 | *params = (GLfloat) obj->RequiredTextureImageUnits; |
||
1550 | break; |
||
1551 | |||
1552 | case GL_TEXTURE_SRGB_DECODE_EXT: |
||
1553 | if (!ctx->Extensions.EXT_texture_sRGB_decode) |
||
1554 | goto invalid_pname; |
||
1555 | *params = (GLfloat) obj->Sampler.sRGBDecode; |
||
1556 | break; |
||
1557 | |||
1558 | default: |
||
1559 | goto invalid_pname; |
||
1560 | } |
||
1561 | |||
1562 | /* no error if we get here */ |
||
1563 | _mesa_unlock_texture(ctx, obj); |
||
1564 | return; |
||
1565 | |||
1566 | invalid_pname: |
||
1567 | _mesa_unlock_texture(ctx, obj); |
||
1568 | _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", pname); |
||
1569 | } |
||
1570 | |||
1571 | |||
1572 | void GLAPIENTRY |
||
1573 | _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) |
||
1574 | { |
||
1575 | struct gl_texture_object *obj; |
||
1576 | GET_CURRENT_CONTEXT(ctx); |
||
1577 | |||
1578 | obj = get_texobj(ctx, target, GL_TRUE); |
||
1579 | if (!obj) |
||
1580 | return; |
||
1581 | |||
1582 | _mesa_lock_texture(ctx, obj); |
||
1583 | switch (pname) { |
||
1584 | case GL_TEXTURE_MAG_FILTER: |
||
1585 | *params = (GLint) obj->Sampler.MagFilter; |
||
1586 | break; |
||
1587 | case GL_TEXTURE_MIN_FILTER: |
||
1588 | *params = (GLint) obj->Sampler.MinFilter; |
||
1589 | break; |
||
1590 | case GL_TEXTURE_WRAP_S: |
||
1591 | *params = (GLint) obj->Sampler.WrapS; |
||
1592 | break; |
||
1593 | case GL_TEXTURE_WRAP_T: |
||
1594 | *params = (GLint) obj->Sampler.WrapT; |
||
1595 | break; |
||
1596 | case GL_TEXTURE_WRAP_R: |
||
1597 | *params = (GLint) obj->Sampler.WrapR; |
||
1598 | break; |
||
1599 | case GL_TEXTURE_BORDER_COLOR: |
||
1600 | if (!_mesa_is_desktop_gl(ctx)) |
||
1601 | goto invalid_pname; |
||
1602 | |||
1603 | { |
||
1604 | GLfloat b[4]; |
||
1605 | b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F); |
||
1606 | b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F); |
||
1607 | b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F); |
||
1608 | b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F); |
||
1609 | params[0] = FLOAT_TO_INT(b[0]); |
||
1610 | params[1] = FLOAT_TO_INT(b[1]); |
||
1611 | params[2] = FLOAT_TO_INT(b[2]); |
||
1612 | params[3] = FLOAT_TO_INT(b[3]); |
||
1613 | } |
||
1614 | break; |
||
1615 | case GL_TEXTURE_RESIDENT: |
||
1616 | if (ctx->API != API_OPENGL_COMPAT) |
||
1617 | goto invalid_pname; |
||
1618 | |||
1619 | *params = 1; |
||
1620 | break; |
||
1621 | case GL_TEXTURE_PRIORITY: |
||
1622 | if (ctx->API != API_OPENGL_COMPAT) |
||
1623 | goto invalid_pname; |
||
1624 | |||
1625 | *params = FLOAT_TO_INT(obj->Priority); |
||
1626 | break; |
||
1627 | case GL_TEXTURE_MIN_LOD: |
||
1628 | if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) |
||
1629 | goto invalid_pname; |
||
1630 | |||
1631 | *params = (GLint) obj->Sampler.MinLod; |
||
1632 | break; |
||
1633 | case GL_TEXTURE_MAX_LOD: |
||
1634 | if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) |
||
1635 | goto invalid_pname; |
||
1636 | |||
1637 | *params = (GLint) obj->Sampler.MaxLod; |
||
1638 | break; |
||
1639 | case GL_TEXTURE_BASE_LEVEL: |
||
1640 | if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) |
||
1641 | goto invalid_pname; |
||
1642 | |||
1643 | *params = obj->BaseLevel; |
||
1644 | break; |
||
1645 | case GL_TEXTURE_MAX_LEVEL: |
||
1646 | *params = obj->MaxLevel; |
||
1647 | break; |
||
1648 | case GL_TEXTURE_MAX_ANISOTROPY_EXT: |
||
1649 | if (!ctx->Extensions.EXT_texture_filter_anisotropic) |
||
1650 | goto invalid_pname; |
||
1651 | *params = (GLint) obj->Sampler.MaxAnisotropy; |
||
1652 | break; |
||
1653 | case GL_GENERATE_MIPMAP_SGIS: |
||
1654 | if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) |
||
1655 | goto invalid_pname; |
||
1656 | |||
1657 | *params = (GLint) obj->GenerateMipmap; |
||
1658 | break; |
||
1659 | case GL_TEXTURE_COMPARE_MODE_ARB: |
||
1660 | if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) |
||
1661 | && !_mesa_is_gles3(ctx)) |
||
1662 | goto invalid_pname; |
||
1663 | *params = (GLint) obj->Sampler.CompareMode; |
||
1664 | break; |
||
1665 | case GL_TEXTURE_COMPARE_FUNC_ARB: |
||
1666 | if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) |
||
1667 | && !_mesa_is_gles3(ctx)) |
||
1668 | goto invalid_pname; |
||
1669 | *params = (GLint) obj->Sampler.CompareFunc; |
||
1670 | break; |
||
1671 | case GL_DEPTH_TEXTURE_MODE_ARB: |
||
1672 | if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture) |
||
1673 | goto invalid_pname; |
||
1674 | *params = (GLint) obj->DepthMode; |
||
1675 | break; |
||
1676 | case GL_TEXTURE_LOD_BIAS: |
||
4401 | Serge | 1677 | if (_mesa_is_gles(ctx)) |
4358 | Serge | 1678 | goto invalid_pname; |
1679 | |||
4401 | Serge | 1680 | /* GL spec 'Data Conversions' section specifies that floating-point |
1681 | * value in integer Get function is rounded to nearest integer |
||
1682 | */ |
||
1683 | *params = (GLint) roundf(obj->Sampler.LodBias); |
||
4358 | Serge | 1684 | break; |
1685 | case GL_TEXTURE_CROP_RECT_OES: |
||
1686 | if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture) |
||
1687 | goto invalid_pname; |
||
1688 | |||
1689 | params[0] = obj->CropRect[0]; |
||
1690 | params[1] = obj->CropRect[1]; |
||
1691 | params[2] = obj->CropRect[2]; |
||
1692 | params[3] = obj->CropRect[3]; |
||
1693 | break; |
||
1694 | case GL_TEXTURE_SWIZZLE_R_EXT: |
||
1695 | case GL_TEXTURE_SWIZZLE_G_EXT: |
||
1696 | case GL_TEXTURE_SWIZZLE_B_EXT: |
||
1697 | case GL_TEXTURE_SWIZZLE_A_EXT: |
||
1698 | if ((!_mesa_is_desktop_gl(ctx) |
||
1699 | || !ctx->Extensions.EXT_texture_swizzle) |
||
1700 | && !_mesa_is_gles3(ctx)) |
||
1701 | goto invalid_pname; |
||
1702 | *params = obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT]; |
||
1703 | break; |
||
1704 | |||
1705 | case GL_TEXTURE_SWIZZLE_RGBA_EXT: |
||
1706 | if ((!_mesa_is_desktop_gl(ctx) |
||
1707 | || !ctx->Extensions.EXT_texture_swizzle) |
||
1708 | && !_mesa_is_gles3(ctx)) |
||
1709 | goto invalid_pname; |
||
1710 | COPY_4V(params, obj->Swizzle); |
||
1711 | break; |
||
1712 | |||
1713 | case GL_TEXTURE_CUBE_MAP_SEAMLESS: |
||
1714 | if (!_mesa_is_desktop_gl(ctx) |
||
1715 | || !ctx->Extensions.AMD_seamless_cubemap_per_texture) |
||
1716 | goto invalid_pname; |
||
1717 | *params = (GLint) obj->Sampler.CubeMapSeamless; |
||
1718 | break; |
||
1719 | |||
1720 | case GL_TEXTURE_IMMUTABLE_FORMAT: |
||
1721 | *params = (GLint) obj->Immutable; |
||
1722 | break; |
||
1723 | |||
1724 | case GL_TEXTURE_IMMUTABLE_LEVELS: |
||
1725 | if (!_mesa_is_gles3(ctx)) |
||
1726 | goto invalid_pname; |
||
1727 | *params = obj->ImmutableLevels; |
||
1728 | break; |
||
1729 | |||
1730 | case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: |
||
1731 | if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external) |
||
1732 | goto invalid_pname; |
||
1733 | *params = obj->RequiredTextureImageUnits; |
||
1734 | break; |
||
1735 | |||
1736 | case GL_TEXTURE_SRGB_DECODE_EXT: |
||
1737 | if (!ctx->Extensions.EXT_texture_sRGB_decode) |
||
1738 | goto invalid_pname; |
||
1739 | *params = obj->Sampler.sRGBDecode; |
||
1740 | break; |
||
1741 | |||
1742 | default: |
||
1743 | goto invalid_pname; |
||
1744 | } |
||
1745 | |||
1746 | /* no error if we get here */ |
||
1747 | _mesa_unlock_texture(ctx, obj); |
||
1748 | return; |
||
1749 | |||
1750 | invalid_pname: |
||
1751 | _mesa_unlock_texture(ctx, obj); |
||
1752 | _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname); |
||
1753 | } |
||
1754 | |||
1755 | |||
1756 | /** New in GL 3.0 */ |
||
1757 | void GLAPIENTRY |
||
1758 | _mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params) |
||
1759 | { |
||
1760 | struct gl_texture_object *texObj; |
||
1761 | GET_CURRENT_CONTEXT(ctx); |
||
1762 | |||
1763 | texObj = get_texobj(ctx, target, GL_TRUE); |
||
1764 | if (!texObj) |
||
1765 | return; |
||
1766 | |||
1767 | switch (pname) { |
||
1768 | case GL_TEXTURE_BORDER_COLOR: |
||
1769 | COPY_4V(params, texObj->Sampler.BorderColor.i); |
||
1770 | break; |
||
1771 | default: |
||
1772 | _mesa_GetTexParameteriv(target, pname, params); |
||
1773 | } |
||
1774 | } |
||
1775 | |||
1776 | |||
1777 | /** New in GL 3.0 */ |
||
1778 | void GLAPIENTRY |
||
1779 | _mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params) |
||
1780 | { |
||
1781 | struct gl_texture_object *texObj; |
||
1782 | GET_CURRENT_CONTEXT(ctx); |
||
1783 | |||
1784 | texObj = get_texobj(ctx, target, GL_TRUE); |
||
1785 | if (!texObj) |
||
1786 | return; |
||
1787 | |||
1788 | switch (pname) { |
||
1789 | case GL_TEXTURE_BORDER_COLOR: |
||
1790 | COPY_4V(params, texObj->Sampler.BorderColor.i); |
||
1791 | break; |
||
1792 | default: |
||
1793 | { |
||
1794 | GLint ip[4]; |
||
1795 | _mesa_GetTexParameteriv(target, pname, ip); |
||
1796 | params[0] = ip[0]; |
||
1797 | if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT || |
||
1798 | pname == GL_TEXTURE_CROP_RECT_OES) { |
||
1799 | params[1] = ip[1]; |
||
1800 | params[2] = ip[2]; |
||
1801 | params[3] = ip[3]; |
||
1802 | } |
||
1803 | } |
||
1804 | } |
||
1805 | }>>>>>>>>>>>><>><>=>> |