1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Mesa 3-D graphics library
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5bf215546Sopenharmony_ci * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
6bf215546Sopenharmony_ci *
7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
10bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
12bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included
15bf215546Sopenharmony_ci * in all copies or substantial portions of the Software.
16bf215546Sopenharmony_ci *
17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
24bf215546Sopenharmony_ci */
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci/**
27bf215546Sopenharmony_ci * \file texenv.c
28bf215546Sopenharmony_ci *
29bf215546Sopenharmony_ci * glTexEnv-related functions
30bf215546Sopenharmony_ci */
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ci#include "main/glheader.h"
34bf215546Sopenharmony_ci#include "main/context.h"
35bf215546Sopenharmony_ci#include "main/blend.h"
36bf215546Sopenharmony_ci#include "main/enums.h"
37bf215546Sopenharmony_ci#include "main/macros.h"
38bf215546Sopenharmony_ci#include "main/mtypes.h"
39bf215546Sopenharmony_ci#include "main/state.h"
40bf215546Sopenharmony_ci#include "main/texstate.h"
41bf215546Sopenharmony_ci#include "api_exec_decl.h"
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_ci
44bf215546Sopenharmony_ci#define TE_ERROR(errCode, msg, value)				\
45bf215546Sopenharmony_ci   _mesa_error(ctx, errCode, msg, _mesa_enum_to_string(value));
46bf215546Sopenharmony_ci
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_ci/** Set texture env mode */
49bf215546Sopenharmony_cistatic void
50bf215546Sopenharmony_ciset_env_mode(struct gl_context *ctx,
51bf215546Sopenharmony_ci             struct gl_fixedfunc_texture_unit *texUnit,
52bf215546Sopenharmony_ci             GLenum mode)
53bf215546Sopenharmony_ci{
54bf215546Sopenharmony_ci   GLboolean legal;
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_ci   if (texUnit->EnvMode == mode)
57bf215546Sopenharmony_ci      return;
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_ci   switch (mode) {
60bf215546Sopenharmony_ci   case GL_MODULATE:
61bf215546Sopenharmony_ci   case GL_BLEND:
62bf215546Sopenharmony_ci   case GL_DECAL:
63bf215546Sopenharmony_ci   case GL_REPLACE:
64bf215546Sopenharmony_ci   case GL_ADD:
65bf215546Sopenharmony_ci   case GL_COMBINE:
66bf215546Sopenharmony_ci      legal = GL_TRUE;
67bf215546Sopenharmony_ci      break;
68bf215546Sopenharmony_ci   case GL_REPLACE_EXT:
69bf215546Sopenharmony_ci      mode = GL_REPLACE; /* GL_REPLACE_EXT != GL_REPLACE */
70bf215546Sopenharmony_ci      legal = GL_TRUE;
71bf215546Sopenharmony_ci      break;
72bf215546Sopenharmony_ci   case GL_COMBINE4_NV:
73bf215546Sopenharmony_ci      legal = ctx->Extensions.NV_texture_env_combine4;
74bf215546Sopenharmony_ci      break;
75bf215546Sopenharmony_ci   default:
76bf215546Sopenharmony_ci      legal = GL_FALSE;
77bf215546Sopenharmony_ci   }
78bf215546Sopenharmony_ci
79bf215546Sopenharmony_ci   if (legal) {
80bf215546Sopenharmony_ci      FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT);
81bf215546Sopenharmony_ci      texUnit->EnvMode = mode;
82bf215546Sopenharmony_ci   }
83bf215546Sopenharmony_ci   else {
84bf215546Sopenharmony_ci      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
85bf215546Sopenharmony_ci   }
86bf215546Sopenharmony_ci}
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_cistatic void
90bf215546Sopenharmony_ciset_env_color(struct gl_context *ctx,
91bf215546Sopenharmony_ci              struct gl_fixedfunc_texture_unit *texUnit,
92bf215546Sopenharmony_ci              const GLfloat *color)
93bf215546Sopenharmony_ci{
94bf215546Sopenharmony_ci   if (TEST_EQ_4V(color, texUnit->EnvColorUnclamped))
95bf215546Sopenharmony_ci      return;
96bf215546Sopenharmony_ci   FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT);
97bf215546Sopenharmony_ci   COPY_4FV(texUnit->EnvColorUnclamped, color);
98bf215546Sopenharmony_ci   texUnit->EnvColor[0] = CLAMP(color[0], 0.0F, 1.0F);
99bf215546Sopenharmony_ci   texUnit->EnvColor[1] = CLAMP(color[1], 0.0F, 1.0F);
100bf215546Sopenharmony_ci   texUnit->EnvColor[2] = CLAMP(color[2], 0.0F, 1.0F);
101bf215546Sopenharmony_ci   texUnit->EnvColor[3] = CLAMP(color[3], 0.0F, 1.0F);
102bf215546Sopenharmony_ci}
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci/** Set an RGB or A combiner mode/function */
106bf215546Sopenharmony_cistatic bool
107bf215546Sopenharmony_ciset_combiner_mode(struct gl_context *ctx,
108bf215546Sopenharmony_ci                  struct gl_fixedfunc_texture_unit *texUnit,
109bf215546Sopenharmony_ci                  GLenum pname, GLenum mode)
110bf215546Sopenharmony_ci{
111bf215546Sopenharmony_ci   GLboolean legal;
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci   switch (mode) {
114bf215546Sopenharmony_ci   case GL_REPLACE:
115bf215546Sopenharmony_ci   case GL_MODULATE:
116bf215546Sopenharmony_ci   case GL_ADD:
117bf215546Sopenharmony_ci   case GL_ADD_SIGNED:
118bf215546Sopenharmony_ci   case GL_INTERPOLATE:
119bf215546Sopenharmony_ci   case GL_SUBTRACT:
120bf215546Sopenharmony_ci      legal = GL_TRUE;
121bf215546Sopenharmony_ci      break;
122bf215546Sopenharmony_ci   case GL_DOT3_RGB_EXT:
123bf215546Sopenharmony_ci   case GL_DOT3_RGBA_EXT:
124bf215546Sopenharmony_ci      legal = (ctx->API == API_OPENGL_COMPAT &&
125bf215546Sopenharmony_ci               ctx->Extensions.EXT_texture_env_dot3 &&
126bf215546Sopenharmony_ci               pname == GL_COMBINE_RGB);
127bf215546Sopenharmony_ci      break;
128bf215546Sopenharmony_ci   case GL_DOT3_RGB:
129bf215546Sopenharmony_ci   case GL_DOT3_RGBA:
130bf215546Sopenharmony_ci      legal = (pname == GL_COMBINE_RGB);
131bf215546Sopenharmony_ci      break;
132bf215546Sopenharmony_ci   case GL_MODULATE_ADD_ATI:
133bf215546Sopenharmony_ci   case GL_MODULATE_SIGNED_ADD_ATI:
134bf215546Sopenharmony_ci   case GL_MODULATE_SUBTRACT_ATI:
135bf215546Sopenharmony_ci      legal = (ctx->API == API_OPENGL_COMPAT &&
136bf215546Sopenharmony_ci               ctx->Extensions.ATI_texture_env_combine3);
137bf215546Sopenharmony_ci      break;
138bf215546Sopenharmony_ci   default:
139bf215546Sopenharmony_ci      legal = GL_FALSE;
140bf215546Sopenharmony_ci   }
141bf215546Sopenharmony_ci
142bf215546Sopenharmony_ci   if (!legal) {
143bf215546Sopenharmony_ci      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
144bf215546Sopenharmony_ci      return false;
145bf215546Sopenharmony_ci   }
146bf215546Sopenharmony_ci
147bf215546Sopenharmony_ci   switch (pname) {
148bf215546Sopenharmony_ci   case GL_COMBINE_RGB:
149bf215546Sopenharmony_ci      if (texUnit->Combine.ModeRGB == mode)
150bf215546Sopenharmony_ci         return true;
151bf215546Sopenharmony_ci      FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT);
152bf215546Sopenharmony_ci      texUnit->Combine.ModeRGB = mode;
153bf215546Sopenharmony_ci      break;
154bf215546Sopenharmony_ci
155bf215546Sopenharmony_ci   case GL_COMBINE_ALPHA:
156bf215546Sopenharmony_ci      if (texUnit->Combine.ModeA == mode)
157bf215546Sopenharmony_ci         return true;
158bf215546Sopenharmony_ci      FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT);
159bf215546Sopenharmony_ci      texUnit->Combine.ModeA = mode;
160bf215546Sopenharmony_ci      break;
161bf215546Sopenharmony_ci   default:
162bf215546Sopenharmony_ci      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
163bf215546Sopenharmony_ci      return false;
164bf215546Sopenharmony_ci   }
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_ci   return true;
167bf215546Sopenharmony_ci}
168bf215546Sopenharmony_ci
169bf215546Sopenharmony_ci
170bf215546Sopenharmony_ci
171bf215546Sopenharmony_ci/** Set an RGB or A combiner source term */
172bf215546Sopenharmony_cistatic bool
173bf215546Sopenharmony_ciset_combiner_source(struct gl_context *ctx,
174bf215546Sopenharmony_ci                    struct gl_fixedfunc_texture_unit *texUnit,
175bf215546Sopenharmony_ci                    GLenum pname, GLenum param)
176bf215546Sopenharmony_ci{
177bf215546Sopenharmony_ci   GLuint term;
178bf215546Sopenharmony_ci   GLboolean alpha, legal;
179bf215546Sopenharmony_ci
180bf215546Sopenharmony_ci   /*
181bf215546Sopenharmony_ci    * Translate pname to (term, alpha).
182bf215546Sopenharmony_ci    *
183bf215546Sopenharmony_ci    * The enums were given sequential values for a reason.
184bf215546Sopenharmony_ci    */
185bf215546Sopenharmony_ci   switch (pname) {
186bf215546Sopenharmony_ci   case GL_SOURCE0_RGB:
187bf215546Sopenharmony_ci   case GL_SOURCE1_RGB:
188bf215546Sopenharmony_ci   case GL_SOURCE2_RGB:
189bf215546Sopenharmony_ci   case GL_SOURCE3_RGB_NV:
190bf215546Sopenharmony_ci      term = pname - GL_SOURCE0_RGB;
191bf215546Sopenharmony_ci      alpha = GL_FALSE;
192bf215546Sopenharmony_ci      break;
193bf215546Sopenharmony_ci   case GL_SOURCE0_ALPHA:
194bf215546Sopenharmony_ci   case GL_SOURCE1_ALPHA:
195bf215546Sopenharmony_ci   case GL_SOURCE2_ALPHA:
196bf215546Sopenharmony_ci   case GL_SOURCE3_ALPHA_NV:
197bf215546Sopenharmony_ci      term = pname - GL_SOURCE0_ALPHA;
198bf215546Sopenharmony_ci      alpha = GL_TRUE;
199bf215546Sopenharmony_ci      break;
200bf215546Sopenharmony_ci   default:
201bf215546Sopenharmony_ci      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
202bf215546Sopenharmony_ci      return false;
203bf215546Sopenharmony_ci   }
204bf215546Sopenharmony_ci
205bf215546Sopenharmony_ci   if ((term == 3) && (ctx->API != API_OPENGL_COMPAT
206bf215546Sopenharmony_ci                       || !ctx->Extensions.NV_texture_env_combine4)) {
207bf215546Sopenharmony_ci      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
208bf215546Sopenharmony_ci      return false;
209bf215546Sopenharmony_ci   }
210bf215546Sopenharmony_ci
211bf215546Sopenharmony_ci   assert(term < MAX_COMBINER_TERMS);
212bf215546Sopenharmony_ci
213bf215546Sopenharmony_ci   /*
214bf215546Sopenharmony_ci    * Error-check param (the source term)
215bf215546Sopenharmony_ci    */
216bf215546Sopenharmony_ci   switch (param) {
217bf215546Sopenharmony_ci   case GL_TEXTURE:
218bf215546Sopenharmony_ci   case GL_CONSTANT:
219bf215546Sopenharmony_ci   case GL_PRIMARY_COLOR:
220bf215546Sopenharmony_ci   case GL_PREVIOUS:
221bf215546Sopenharmony_ci      legal = GL_TRUE;
222bf215546Sopenharmony_ci      break;
223bf215546Sopenharmony_ci   case GL_TEXTURE0:
224bf215546Sopenharmony_ci   case GL_TEXTURE1:
225bf215546Sopenharmony_ci   case GL_TEXTURE2:
226bf215546Sopenharmony_ci   case GL_TEXTURE3:
227bf215546Sopenharmony_ci   case GL_TEXTURE4:
228bf215546Sopenharmony_ci   case GL_TEXTURE5:
229bf215546Sopenharmony_ci   case GL_TEXTURE6:
230bf215546Sopenharmony_ci   case GL_TEXTURE7:
231bf215546Sopenharmony_ci      legal = (param - GL_TEXTURE0 < ctx->Const.MaxTextureUnits);
232bf215546Sopenharmony_ci      break;
233bf215546Sopenharmony_ci   case GL_ZERO:
234bf215546Sopenharmony_ci      legal = (ctx->API == API_OPENGL_COMPAT &&
235bf215546Sopenharmony_ci               (ctx->Extensions.ATI_texture_env_combine3 ||
236bf215546Sopenharmony_ci                ctx->Extensions.NV_texture_env_combine4));
237bf215546Sopenharmony_ci      break;
238bf215546Sopenharmony_ci   case GL_ONE:
239bf215546Sopenharmony_ci      legal = (ctx->API == API_OPENGL_COMPAT &&
240bf215546Sopenharmony_ci               ctx->Extensions.ATI_texture_env_combine3);
241bf215546Sopenharmony_ci      break;
242bf215546Sopenharmony_ci   default:
243bf215546Sopenharmony_ci      legal = GL_FALSE;
244bf215546Sopenharmony_ci   }
245bf215546Sopenharmony_ci
246bf215546Sopenharmony_ci   if (!legal) {
247bf215546Sopenharmony_ci      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", param);
248bf215546Sopenharmony_ci      return false;
249bf215546Sopenharmony_ci   }
250bf215546Sopenharmony_ci
251bf215546Sopenharmony_ci   FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT);
252bf215546Sopenharmony_ci
253bf215546Sopenharmony_ci   if (alpha)
254bf215546Sopenharmony_ci      texUnit->Combine.SourceA[term] = param;
255bf215546Sopenharmony_ci   else
256bf215546Sopenharmony_ci      texUnit->Combine.SourceRGB[term] = param;
257bf215546Sopenharmony_ci
258bf215546Sopenharmony_ci   return true;
259bf215546Sopenharmony_ci}
260bf215546Sopenharmony_ci
261bf215546Sopenharmony_ci
262bf215546Sopenharmony_ci/** Set an RGB or A combiner operand term */
263bf215546Sopenharmony_cistatic bool
264bf215546Sopenharmony_ciset_combiner_operand(struct gl_context *ctx,
265bf215546Sopenharmony_ci                     struct gl_fixedfunc_texture_unit *texUnit,
266bf215546Sopenharmony_ci                     GLenum pname, GLenum param)
267bf215546Sopenharmony_ci{
268bf215546Sopenharmony_ci   GLuint term;
269bf215546Sopenharmony_ci   GLboolean alpha, legal;
270bf215546Sopenharmony_ci
271bf215546Sopenharmony_ci   /* The enums were given sequential values for a reason.
272bf215546Sopenharmony_ci    */
273bf215546Sopenharmony_ci   switch (pname) {
274bf215546Sopenharmony_ci   case GL_OPERAND0_RGB:
275bf215546Sopenharmony_ci   case GL_OPERAND1_RGB:
276bf215546Sopenharmony_ci   case GL_OPERAND2_RGB:
277bf215546Sopenharmony_ci   case GL_OPERAND3_RGB_NV:
278bf215546Sopenharmony_ci      term = pname - GL_OPERAND0_RGB;
279bf215546Sopenharmony_ci      alpha = GL_FALSE;
280bf215546Sopenharmony_ci      break;
281bf215546Sopenharmony_ci   case GL_OPERAND0_ALPHA:
282bf215546Sopenharmony_ci   case GL_OPERAND1_ALPHA:
283bf215546Sopenharmony_ci   case GL_OPERAND2_ALPHA:
284bf215546Sopenharmony_ci   case GL_OPERAND3_ALPHA_NV:
285bf215546Sopenharmony_ci      term = pname - GL_OPERAND0_ALPHA;
286bf215546Sopenharmony_ci      alpha = GL_TRUE;
287bf215546Sopenharmony_ci      break;
288bf215546Sopenharmony_ci   default:
289bf215546Sopenharmony_ci      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
290bf215546Sopenharmony_ci      return false;
291bf215546Sopenharmony_ci   }
292bf215546Sopenharmony_ci
293bf215546Sopenharmony_ci   if ((term == 3) && (ctx->API != API_OPENGL_COMPAT
294bf215546Sopenharmony_ci                       || !ctx->Extensions.NV_texture_env_combine4)) {
295bf215546Sopenharmony_ci      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
296bf215546Sopenharmony_ci      return false;
297bf215546Sopenharmony_ci   }
298bf215546Sopenharmony_ci
299bf215546Sopenharmony_ci   assert(term < MAX_COMBINER_TERMS);
300bf215546Sopenharmony_ci
301bf215546Sopenharmony_ci   /*
302bf215546Sopenharmony_ci    * Error-check param (the source operand)
303bf215546Sopenharmony_ci    */
304bf215546Sopenharmony_ci   switch (param) {
305bf215546Sopenharmony_ci   case GL_SRC_COLOR:
306bf215546Sopenharmony_ci   case GL_ONE_MINUS_SRC_COLOR:
307bf215546Sopenharmony_ci      legal = !alpha;
308bf215546Sopenharmony_ci      break;
309bf215546Sopenharmony_ci   case GL_ONE_MINUS_SRC_ALPHA:
310bf215546Sopenharmony_ci   case GL_SRC_ALPHA:
311bf215546Sopenharmony_ci      legal = GL_TRUE;
312bf215546Sopenharmony_ci      break;
313bf215546Sopenharmony_ci   default:
314bf215546Sopenharmony_ci      legal = GL_FALSE;
315bf215546Sopenharmony_ci   }
316bf215546Sopenharmony_ci
317bf215546Sopenharmony_ci   if (!legal) {
318bf215546Sopenharmony_ci      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", param);
319bf215546Sopenharmony_ci      return false;
320bf215546Sopenharmony_ci   }
321bf215546Sopenharmony_ci
322bf215546Sopenharmony_ci   FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT);
323bf215546Sopenharmony_ci
324bf215546Sopenharmony_ci   if (alpha)
325bf215546Sopenharmony_ci      texUnit->Combine.OperandA[term] = param;
326bf215546Sopenharmony_ci   else
327bf215546Sopenharmony_ci      texUnit->Combine.OperandRGB[term] = param;
328bf215546Sopenharmony_ci
329bf215546Sopenharmony_ci   return true;
330bf215546Sopenharmony_ci}
331bf215546Sopenharmony_ci
332bf215546Sopenharmony_ci
333bf215546Sopenharmony_cistatic bool
334bf215546Sopenharmony_ciset_combiner_scale(struct gl_context *ctx,
335bf215546Sopenharmony_ci                   struct gl_fixedfunc_texture_unit *texUnit,
336bf215546Sopenharmony_ci                   GLenum pname, GLfloat scale)
337bf215546Sopenharmony_ci{
338bf215546Sopenharmony_ci   GLuint shift;
339bf215546Sopenharmony_ci
340bf215546Sopenharmony_ci   if (scale == 1.0F) {
341bf215546Sopenharmony_ci      shift = 0;
342bf215546Sopenharmony_ci   }
343bf215546Sopenharmony_ci   else if (scale == 2.0F) {
344bf215546Sopenharmony_ci      shift = 1;
345bf215546Sopenharmony_ci   }
346bf215546Sopenharmony_ci   else if (scale == 4.0F) {
347bf215546Sopenharmony_ci      shift = 2;
348bf215546Sopenharmony_ci   }
349bf215546Sopenharmony_ci   else {
350bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_VALUE,
351bf215546Sopenharmony_ci                   "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
352bf215546Sopenharmony_ci      return false;
353bf215546Sopenharmony_ci   }
354bf215546Sopenharmony_ci
355bf215546Sopenharmony_ci   switch (pname) {
356bf215546Sopenharmony_ci   case GL_RGB_SCALE:
357bf215546Sopenharmony_ci      if (texUnit->Combine.ScaleShiftRGB == shift)
358bf215546Sopenharmony_ci         return true;
359bf215546Sopenharmony_ci      FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT);
360bf215546Sopenharmony_ci      texUnit->Combine.ScaleShiftRGB = shift;
361bf215546Sopenharmony_ci      break;
362bf215546Sopenharmony_ci   case GL_ALPHA_SCALE:
363bf215546Sopenharmony_ci      if (texUnit->Combine.ScaleShiftA == shift)
364bf215546Sopenharmony_ci         return true;
365bf215546Sopenharmony_ci      FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT);
366bf215546Sopenharmony_ci      texUnit->Combine.ScaleShiftA = shift;
367bf215546Sopenharmony_ci      break;
368bf215546Sopenharmony_ci   default:
369bf215546Sopenharmony_ci      TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
370bf215546Sopenharmony_ci      return false;
371bf215546Sopenharmony_ci   }
372bf215546Sopenharmony_ci
373bf215546Sopenharmony_ci   return true;
374bf215546Sopenharmony_ci}
375bf215546Sopenharmony_ci
376bf215546Sopenharmony_ci
377bf215546Sopenharmony_cistatic void
378bf215546Sopenharmony_ci_mesa_texenvfv_indexed( struct gl_context* ctx, GLuint texunit, GLenum target,
379bf215546Sopenharmony_ci                        GLenum pname, const GLfloat *param )
380bf215546Sopenharmony_ci{
381bf215546Sopenharmony_ci   const GLint iparam0 = (GLint) param[0];
382bf215546Sopenharmony_ci   GLuint maxUnit;
383bf215546Sopenharmony_ci
384bf215546Sopenharmony_ci   maxUnit = (target == GL_POINT_SPRITE && pname == GL_COORD_REPLACE)
385bf215546Sopenharmony_ci      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxCombinedTextureImageUnits;
386bf215546Sopenharmony_ci   if (texunit >= maxUnit) {
387bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexEnvfv(texunit=%d)", texunit);
388bf215546Sopenharmony_ci      return;
389bf215546Sopenharmony_ci   }
390bf215546Sopenharmony_ci
391bf215546Sopenharmony_ci   if (target == GL_TEXTURE_ENV) {
392bf215546Sopenharmony_ci      struct gl_fixedfunc_texture_unit *texUnit =
393bf215546Sopenharmony_ci         _mesa_get_fixedfunc_tex_unit(ctx, texunit);
394bf215546Sopenharmony_ci
395bf215546Sopenharmony_ci      /* The GL spec says that we should report an error if the unit is greater
396bf215546Sopenharmony_ci       * than GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, but in practice, only
397bf215546Sopenharmony_ci       * fixed-function units are usable. This is probably a spec bug.
398bf215546Sopenharmony_ci       * Ignore glTexEnv(GL_TEXTURE_ENV) calls for non-fixed-func units,
399bf215546Sopenharmony_ci       * because we don't want to process calls that have no effect.
400bf215546Sopenharmony_ci       */
401bf215546Sopenharmony_ci      if (!texUnit)
402bf215546Sopenharmony_ci         return;
403bf215546Sopenharmony_ci
404bf215546Sopenharmony_ci      switch (pname) {
405bf215546Sopenharmony_ci      case GL_TEXTURE_ENV_MODE:
406bf215546Sopenharmony_ci         set_env_mode(ctx, texUnit, (GLenum) iparam0);
407bf215546Sopenharmony_ci         break;
408bf215546Sopenharmony_ci      case GL_TEXTURE_ENV_COLOR:
409bf215546Sopenharmony_ci         set_env_color(ctx, texUnit, param);
410bf215546Sopenharmony_ci         break;
411bf215546Sopenharmony_ci      case GL_COMBINE_RGB:
412bf215546Sopenharmony_ci      case GL_COMBINE_ALPHA:
413bf215546Sopenharmony_ci         if (!set_combiner_mode(ctx, texUnit, pname, (GLenum) iparam0))
414bf215546Sopenharmony_ci            return;
415bf215546Sopenharmony_ci	 break;
416bf215546Sopenharmony_ci      case GL_SOURCE0_RGB:
417bf215546Sopenharmony_ci      case GL_SOURCE1_RGB:
418bf215546Sopenharmony_ci      case GL_SOURCE2_RGB:
419bf215546Sopenharmony_ci      case GL_SOURCE3_RGB_NV:
420bf215546Sopenharmony_ci      case GL_SOURCE0_ALPHA:
421bf215546Sopenharmony_ci      case GL_SOURCE1_ALPHA:
422bf215546Sopenharmony_ci      case GL_SOURCE2_ALPHA:
423bf215546Sopenharmony_ci      case GL_SOURCE3_ALPHA_NV:
424bf215546Sopenharmony_ci         if (!set_combiner_source(ctx, texUnit, pname, (GLenum) iparam0))
425bf215546Sopenharmony_ci            return;
426bf215546Sopenharmony_ci	 break;
427bf215546Sopenharmony_ci      case GL_OPERAND0_RGB:
428bf215546Sopenharmony_ci      case GL_OPERAND1_RGB:
429bf215546Sopenharmony_ci      case GL_OPERAND2_RGB:
430bf215546Sopenharmony_ci      case GL_OPERAND3_RGB_NV:
431bf215546Sopenharmony_ci      case GL_OPERAND0_ALPHA:
432bf215546Sopenharmony_ci      case GL_OPERAND1_ALPHA:
433bf215546Sopenharmony_ci      case GL_OPERAND2_ALPHA:
434bf215546Sopenharmony_ci      case GL_OPERAND3_ALPHA_NV:
435bf215546Sopenharmony_ci         if (!set_combiner_operand(ctx, texUnit, pname, (GLenum) iparam0))
436bf215546Sopenharmony_ci            return;
437bf215546Sopenharmony_ci	 break;
438bf215546Sopenharmony_ci      case GL_RGB_SCALE:
439bf215546Sopenharmony_ci      case GL_ALPHA_SCALE:
440bf215546Sopenharmony_ci         if (!set_combiner_scale(ctx, texUnit, pname, param[0]))
441bf215546Sopenharmony_ci            return;
442bf215546Sopenharmony_ci	 break;
443bf215546Sopenharmony_ci      default:
444bf215546Sopenharmony_ci	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
445bf215546Sopenharmony_ci	 return;
446bf215546Sopenharmony_ci      }
447bf215546Sopenharmony_ci   }
448bf215546Sopenharmony_ci   else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
449bf215546Sopenharmony_ci      struct gl_texture_unit *texUnit =
450bf215546Sopenharmony_ci         _mesa_get_tex_unit(ctx, texunit);
451bf215546Sopenharmony_ci
452bf215546Sopenharmony_ci      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
453bf215546Sopenharmony_ci	 if (texUnit->LodBias == param[0])
454bf215546Sopenharmony_ci	    return;
455bf215546Sopenharmony_ci	 FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT);
456bf215546Sopenharmony_ci         texUnit->LodBias = param[0];
457bf215546Sopenharmony_ci         texUnit->LodBiasQuantized = util_quantize_lod_bias(param[0]);
458bf215546Sopenharmony_ci      }
459bf215546Sopenharmony_ci      else {
460bf215546Sopenharmony_ci         TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
461bf215546Sopenharmony_ci	 return;
462bf215546Sopenharmony_ci      }
463bf215546Sopenharmony_ci   }
464bf215546Sopenharmony_ci   else if (target == GL_POINT_SPRITE) {
465bf215546Sopenharmony_ci      /* GL_ARB_point_sprite */
466bf215546Sopenharmony_ci      if (!ctx->Extensions.ARB_point_sprite) {
467bf215546Sopenharmony_ci	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
468bf215546Sopenharmony_ci	 return;
469bf215546Sopenharmony_ci      }
470bf215546Sopenharmony_ci      if (pname == GL_COORD_REPLACE) {
471bf215546Sopenharmony_ci         /* It's kind of weird to set point state via glTexEnv,
472bf215546Sopenharmony_ci          * but that's what the spec calls for.
473bf215546Sopenharmony_ci          */
474bf215546Sopenharmony_ci         if (iparam0 == GL_TRUE) {
475bf215546Sopenharmony_ci            if (ctx->Point.CoordReplace & (1u << texunit))
476bf215546Sopenharmony_ci               return;
477bf215546Sopenharmony_ci            FLUSH_VERTICES(ctx, _NEW_POINT | _NEW_FF_VERT_PROGRAM,
478bf215546Sopenharmony_ci                           GL_POINT_BIT);
479bf215546Sopenharmony_ci            ctx->Point.CoordReplace |= (1u << texunit);
480bf215546Sopenharmony_ci         } else if (iparam0 == GL_FALSE) {
481bf215546Sopenharmony_ci            if (~(ctx->Point.CoordReplace) & (1u << texunit))
482bf215546Sopenharmony_ci               return;
483bf215546Sopenharmony_ci            FLUSH_VERTICES(ctx, _NEW_POINT | _NEW_FF_VERT_PROGRAM,
484bf215546Sopenharmony_ci                           GL_POINT_BIT);
485bf215546Sopenharmony_ci            ctx->Point.CoordReplace &= ~(1u << texunit);
486bf215546Sopenharmony_ci         } else {
487bf215546Sopenharmony_ci            _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", iparam0);
488bf215546Sopenharmony_ci            return;
489bf215546Sopenharmony_ci         }
490bf215546Sopenharmony_ci      }
491bf215546Sopenharmony_ci      else {
492bf215546Sopenharmony_ci         _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname );
493bf215546Sopenharmony_ci         return;
494bf215546Sopenharmony_ci      }
495bf215546Sopenharmony_ci   }
496bf215546Sopenharmony_ci   else {
497bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_ENUM, "glTexEnv(target=%s)",
498bf215546Sopenharmony_ci                  _mesa_enum_to_string(target));
499bf215546Sopenharmony_ci      return;
500bf215546Sopenharmony_ci   }
501bf215546Sopenharmony_ci
502bf215546Sopenharmony_ci   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
503bf215546Sopenharmony_ci      _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n",
504bf215546Sopenharmony_ci                  _mesa_enum_to_string(target),
505bf215546Sopenharmony_ci                  _mesa_enum_to_string(pname),
506bf215546Sopenharmony_ci                  *param,
507bf215546Sopenharmony_ci                  _mesa_enum_to_string((GLenum) iparam0));
508bf215546Sopenharmony_ci}
509bf215546Sopenharmony_ci
510bf215546Sopenharmony_ci
511bf215546Sopenharmony_civoid GLAPIENTRY
512bf215546Sopenharmony_ci_mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
513bf215546Sopenharmony_ci{
514bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
515bf215546Sopenharmony_ci   _mesa_texenvfv_indexed(ctx, ctx->Texture.CurrentUnit, target, pname, param);
516bf215546Sopenharmony_ci}
517bf215546Sopenharmony_ci
518bf215546Sopenharmony_ci
519bf215546Sopenharmony_civoid GLAPIENTRY
520bf215546Sopenharmony_ci_mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param )
521bf215546Sopenharmony_ci{
522bf215546Sopenharmony_ci   GLfloat p[4];
523bf215546Sopenharmony_ci   p[0] = param;
524bf215546Sopenharmony_ci   p[1] = p[2] = p[3] = 0.0;
525bf215546Sopenharmony_ci   _mesa_TexEnvfv( target, pname, p );
526bf215546Sopenharmony_ci}
527bf215546Sopenharmony_ci
528bf215546Sopenharmony_ci
529bf215546Sopenharmony_civoid GLAPIENTRY
530bf215546Sopenharmony_ci_mesa_TexEnvi( GLenum target, GLenum pname, GLint param )
531bf215546Sopenharmony_ci{
532bf215546Sopenharmony_ci   GLfloat p[4];
533bf215546Sopenharmony_ci   p[0] = (GLfloat) param;
534bf215546Sopenharmony_ci   p[1] = p[2] = p[3] = 0.0;
535bf215546Sopenharmony_ci   _mesa_TexEnvfv( target, pname, p );
536bf215546Sopenharmony_ci}
537bf215546Sopenharmony_ci
538bf215546Sopenharmony_ci
539bf215546Sopenharmony_civoid GLAPIENTRY
540bf215546Sopenharmony_ci_mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param )
541bf215546Sopenharmony_ci{
542bf215546Sopenharmony_ci   GLfloat p[4];
543bf215546Sopenharmony_ci   if (pname == GL_TEXTURE_ENV_COLOR) {
544bf215546Sopenharmony_ci      p[0] = INT_TO_FLOAT( param[0] );
545bf215546Sopenharmony_ci      p[1] = INT_TO_FLOAT( param[1] );
546bf215546Sopenharmony_ci      p[2] = INT_TO_FLOAT( param[2] );
547bf215546Sopenharmony_ci      p[3] = INT_TO_FLOAT( param[3] );
548bf215546Sopenharmony_ci   }
549bf215546Sopenharmony_ci   else {
550bf215546Sopenharmony_ci      p[0] = (GLfloat) param[0];
551bf215546Sopenharmony_ci      p[1] = p[2] = p[3] = 0;  /* init to zero, just to be safe */
552bf215546Sopenharmony_ci   }
553bf215546Sopenharmony_ci   _mesa_TexEnvfv( target, pname, p );
554bf215546Sopenharmony_ci}
555bf215546Sopenharmony_ci
556bf215546Sopenharmony_ci
557bf215546Sopenharmony_civoid GLAPIENTRY
558bf215546Sopenharmony_ci_mesa_MultiTexEnvfEXT( GLenum texunit, GLenum target,
559bf215546Sopenharmony_ci                       GLenum pname, GLfloat param )
560bf215546Sopenharmony_ci{
561bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
562bf215546Sopenharmony_ci   GLfloat p[4];
563bf215546Sopenharmony_ci   p[0] = param;
564bf215546Sopenharmony_ci   p[1] = p[2] = p[3] = 0.0;
565bf215546Sopenharmony_ci   _mesa_texenvfv_indexed(ctx, texunit - GL_TEXTURE0, target, pname, p);
566bf215546Sopenharmony_ci}
567bf215546Sopenharmony_ci
568bf215546Sopenharmony_civoid GLAPIENTRY
569bf215546Sopenharmony_ci_mesa_MultiTexEnvfvEXT( GLenum texunit, GLenum target,
570bf215546Sopenharmony_ci                        GLenum pname, const GLfloat *param )
571bf215546Sopenharmony_ci{
572bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
573bf215546Sopenharmony_ci   _mesa_texenvfv_indexed(ctx, texunit - GL_TEXTURE0, target, pname, param);
574bf215546Sopenharmony_ci}
575bf215546Sopenharmony_ci
576bf215546Sopenharmony_ci
577bf215546Sopenharmony_civoid GLAPIENTRY
578bf215546Sopenharmony_ci_mesa_MultiTexEnviEXT( GLenum texunit, GLenum target,
579bf215546Sopenharmony_ci                       GLenum pname, GLint param )
580bf215546Sopenharmony_ci{
581bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
582bf215546Sopenharmony_ci   GLfloat p[4];
583bf215546Sopenharmony_ci   p[0] = (GLfloat) param;
584bf215546Sopenharmony_ci   p[1] = p[2] = p[3] = 0.0;
585bf215546Sopenharmony_ci   _mesa_texenvfv_indexed( ctx, texunit - GL_TEXTURE0, target, pname, p );
586bf215546Sopenharmony_ci}
587bf215546Sopenharmony_ci
588bf215546Sopenharmony_ci
589bf215546Sopenharmony_civoid GLAPIENTRY
590bf215546Sopenharmony_ci_mesa_MultiTexEnvivEXT( GLenum texunit, GLenum target,
591bf215546Sopenharmony_ci                        GLenum pname, const GLint *param )
592bf215546Sopenharmony_ci{
593bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
594bf215546Sopenharmony_ci   GLfloat p[4];
595bf215546Sopenharmony_ci   if (pname == GL_TEXTURE_ENV_COLOR) {
596bf215546Sopenharmony_ci      p[0] = INT_TO_FLOAT( param[0] );
597bf215546Sopenharmony_ci      p[1] = INT_TO_FLOAT( param[1] );
598bf215546Sopenharmony_ci      p[2] = INT_TO_FLOAT( param[2] );
599bf215546Sopenharmony_ci      p[3] = INT_TO_FLOAT( param[3] );
600bf215546Sopenharmony_ci   }
601bf215546Sopenharmony_ci   else {
602bf215546Sopenharmony_ci      p[0] = (GLfloat) param[0];
603bf215546Sopenharmony_ci      p[1] = p[2] = p[3] = 0;  /* init to zero, just to be safe */
604bf215546Sopenharmony_ci   }
605bf215546Sopenharmony_ci   _mesa_texenvfv_indexed( ctx, texunit - GL_TEXTURE0, target, pname, p );
606bf215546Sopenharmony_ci}
607bf215546Sopenharmony_ci
608bf215546Sopenharmony_ci
609bf215546Sopenharmony_ci
610bf215546Sopenharmony_ci
611bf215546Sopenharmony_ci/**
612bf215546Sopenharmony_ci * Helper for glGetTexEnvi/f()
613bf215546Sopenharmony_ci * \return  value of queried pname or -1 if error.
614bf215546Sopenharmony_ci */
615bf215546Sopenharmony_cistatic GLint
616bf215546Sopenharmony_ciget_texenvi(struct gl_context *ctx,
617bf215546Sopenharmony_ci            const struct gl_fixedfunc_texture_unit *texUnit,
618bf215546Sopenharmony_ci            GLenum pname)
619bf215546Sopenharmony_ci{
620bf215546Sopenharmony_ci   switch (pname) {
621bf215546Sopenharmony_ci   case GL_TEXTURE_ENV_MODE:
622bf215546Sopenharmony_ci      return texUnit->EnvMode;
623bf215546Sopenharmony_ci      break;
624bf215546Sopenharmony_ci   case GL_COMBINE_RGB:
625bf215546Sopenharmony_ci      return texUnit->Combine.ModeRGB;
626bf215546Sopenharmony_ci   case GL_COMBINE_ALPHA:
627bf215546Sopenharmony_ci      return texUnit->Combine.ModeA;
628bf215546Sopenharmony_ci   case GL_SOURCE0_RGB:
629bf215546Sopenharmony_ci   case GL_SOURCE1_RGB:
630bf215546Sopenharmony_ci   case GL_SOURCE2_RGB: {
631bf215546Sopenharmony_ci      const unsigned rgb_idx = pname - GL_SOURCE0_RGB;
632bf215546Sopenharmony_ci      return texUnit->Combine.SourceRGB[rgb_idx];
633bf215546Sopenharmony_ci   }
634bf215546Sopenharmony_ci   case GL_SOURCE3_RGB_NV:
635bf215546Sopenharmony_ci      if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) {
636bf215546Sopenharmony_ci         return texUnit->Combine.SourceRGB[3];
637bf215546Sopenharmony_ci      }
638bf215546Sopenharmony_ci      else {
639bf215546Sopenharmony_ci         _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
640bf215546Sopenharmony_ci      }
641bf215546Sopenharmony_ci      break;
642bf215546Sopenharmony_ci   case GL_SOURCE0_ALPHA:
643bf215546Sopenharmony_ci   case GL_SOURCE1_ALPHA:
644bf215546Sopenharmony_ci   case GL_SOURCE2_ALPHA: {
645bf215546Sopenharmony_ci      const unsigned alpha_idx = pname - GL_SOURCE0_ALPHA;
646bf215546Sopenharmony_ci      return texUnit->Combine.SourceA[alpha_idx];
647bf215546Sopenharmony_ci   }
648bf215546Sopenharmony_ci   case GL_SOURCE3_ALPHA_NV:
649bf215546Sopenharmony_ci      if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) {
650bf215546Sopenharmony_ci         return texUnit->Combine.SourceA[3];
651bf215546Sopenharmony_ci      }
652bf215546Sopenharmony_ci      else {
653bf215546Sopenharmony_ci         _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
654bf215546Sopenharmony_ci      }
655bf215546Sopenharmony_ci      break;
656bf215546Sopenharmony_ci   case GL_OPERAND0_RGB:
657bf215546Sopenharmony_ci   case GL_OPERAND1_RGB:
658bf215546Sopenharmony_ci   case GL_OPERAND2_RGB: {
659bf215546Sopenharmony_ci      const unsigned op_rgb = pname - GL_OPERAND0_RGB;
660bf215546Sopenharmony_ci      return texUnit->Combine.OperandRGB[op_rgb];
661bf215546Sopenharmony_ci   }
662bf215546Sopenharmony_ci   case GL_OPERAND3_RGB_NV:
663bf215546Sopenharmony_ci      if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) {
664bf215546Sopenharmony_ci         return texUnit->Combine.OperandRGB[3];
665bf215546Sopenharmony_ci      }
666bf215546Sopenharmony_ci      else {
667bf215546Sopenharmony_ci         _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
668bf215546Sopenharmony_ci      }
669bf215546Sopenharmony_ci      break;
670bf215546Sopenharmony_ci   case GL_OPERAND0_ALPHA:
671bf215546Sopenharmony_ci   case GL_OPERAND1_ALPHA:
672bf215546Sopenharmony_ci   case GL_OPERAND2_ALPHA: {
673bf215546Sopenharmony_ci      const unsigned op_alpha = pname - GL_OPERAND0_ALPHA;
674bf215546Sopenharmony_ci      return texUnit->Combine.OperandA[op_alpha];
675bf215546Sopenharmony_ci   }
676bf215546Sopenharmony_ci   case GL_OPERAND3_ALPHA_NV:
677bf215546Sopenharmony_ci      if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) {
678bf215546Sopenharmony_ci         return texUnit->Combine.OperandA[3];
679bf215546Sopenharmony_ci      }
680bf215546Sopenharmony_ci      else {
681bf215546Sopenharmony_ci         _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
682bf215546Sopenharmony_ci      }
683bf215546Sopenharmony_ci      break;
684bf215546Sopenharmony_ci   case GL_RGB_SCALE:
685bf215546Sopenharmony_ci      return 1 << texUnit->Combine.ScaleShiftRGB;
686bf215546Sopenharmony_ci   case GL_ALPHA_SCALE:
687bf215546Sopenharmony_ci      return 1 << texUnit->Combine.ScaleShiftA;
688bf215546Sopenharmony_ci   default:
689bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
690bf215546Sopenharmony_ci      break;
691bf215546Sopenharmony_ci   }
692bf215546Sopenharmony_ci
693bf215546Sopenharmony_ci   return -1; /* error */
694bf215546Sopenharmony_ci}
695bf215546Sopenharmony_ci
696bf215546Sopenharmony_ci
697bf215546Sopenharmony_cistatic void
698bf215546Sopenharmony_ci_mesa_gettexenvfv_indexed( GLuint texunit, GLenum target, GLenum pname, GLfloat *params )
699bf215546Sopenharmony_ci{
700bf215546Sopenharmony_ci   GLuint maxUnit;
701bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
702bf215546Sopenharmony_ci
703bf215546Sopenharmony_ci   maxUnit = (target == GL_POINT_SPRITE && pname == GL_COORD_REPLACE)
704bf215546Sopenharmony_ci      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxCombinedTextureImageUnits;
705bf215546Sopenharmony_ci   if (texunit >= maxUnit) {
706bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnvfv(texunit=%d)", texunit);
707bf215546Sopenharmony_ci      return;
708bf215546Sopenharmony_ci   }
709bf215546Sopenharmony_ci
710bf215546Sopenharmony_ci   if (target == GL_TEXTURE_ENV) {
711bf215546Sopenharmony_ci      struct gl_fixedfunc_texture_unit *texUnit =
712bf215546Sopenharmony_ci         _mesa_get_fixedfunc_tex_unit(ctx, texunit);
713bf215546Sopenharmony_ci
714bf215546Sopenharmony_ci      /* The GL spec says that we should report an error if the unit is greater
715bf215546Sopenharmony_ci       * than GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, but in practice, only
716bf215546Sopenharmony_ci       * fixed-function units are usable. This is probably a spec bug.
717bf215546Sopenharmony_ci       * Ignore calls for non-fixed-func units, because we don't process
718bf215546Sopenharmony_ci       * glTexEnv for them either.
719bf215546Sopenharmony_ci       */
720bf215546Sopenharmony_ci      if (!texUnit)
721bf215546Sopenharmony_ci         return;
722bf215546Sopenharmony_ci
723bf215546Sopenharmony_ci      if (pname == GL_TEXTURE_ENV_COLOR) {
724bf215546Sopenharmony_ci         if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer))
725bf215546Sopenharmony_ci            COPY_4FV( params, texUnit->EnvColor );
726bf215546Sopenharmony_ci         else
727bf215546Sopenharmony_ci            COPY_4FV( params, texUnit->EnvColorUnclamped );
728bf215546Sopenharmony_ci      }
729bf215546Sopenharmony_ci      else {
730bf215546Sopenharmony_ci         GLint val = get_texenvi(ctx, texUnit, pname);
731bf215546Sopenharmony_ci         if (val >= 0) {
732bf215546Sopenharmony_ci            *params = (GLfloat) val;
733bf215546Sopenharmony_ci         }
734bf215546Sopenharmony_ci      }
735bf215546Sopenharmony_ci   }
736bf215546Sopenharmony_ci   else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
737bf215546Sopenharmony_ci      const struct gl_texture_unit *texUnit = _mesa_get_tex_unit(ctx, texunit);
738bf215546Sopenharmony_ci
739bf215546Sopenharmony_ci      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
740bf215546Sopenharmony_ci         *params = texUnit->LodBias;
741bf215546Sopenharmony_ci      }
742bf215546Sopenharmony_ci      else {
743bf215546Sopenharmony_ci         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
744bf215546Sopenharmony_ci	 return;
745bf215546Sopenharmony_ci      }
746bf215546Sopenharmony_ci   }
747bf215546Sopenharmony_ci   else if (target == GL_POINT_SPRITE) {
748bf215546Sopenharmony_ci      /* GL_ARB_point_sprite */
749bf215546Sopenharmony_ci      if (!ctx->Extensions.ARB_point_sprite) {
750bf215546Sopenharmony_ci         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
751bf215546Sopenharmony_ci         return;
752bf215546Sopenharmony_ci      }
753bf215546Sopenharmony_ci      if (pname == GL_COORD_REPLACE) {
754bf215546Sopenharmony_ci         if (ctx->Point.CoordReplace & (1u << texunit))
755bf215546Sopenharmony_ci            *params = 1.0f;
756bf215546Sopenharmony_ci         else
757bf215546Sopenharmony_ci            *params = 0.0f;
758bf215546Sopenharmony_ci      }
759bf215546Sopenharmony_ci      else {
760bf215546Sopenharmony_ci         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
761bf215546Sopenharmony_ci         return;
762bf215546Sopenharmony_ci      }
763bf215546Sopenharmony_ci   }
764bf215546Sopenharmony_ci   else {
765bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
766bf215546Sopenharmony_ci      return;
767bf215546Sopenharmony_ci   }
768bf215546Sopenharmony_ci}
769bf215546Sopenharmony_ci
770bf215546Sopenharmony_ci
771bf215546Sopenharmony_cistatic void
772bf215546Sopenharmony_ci_mesa_gettexenviv_indexed( GLuint texunit, GLenum target,
773bf215546Sopenharmony_ci                           GLenum pname, GLint *params )
774bf215546Sopenharmony_ci{
775bf215546Sopenharmony_ci   GLuint maxUnit;
776bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
777bf215546Sopenharmony_ci
778bf215546Sopenharmony_ci   maxUnit = (target == GL_POINT_SPRITE && pname == GL_COORD_REPLACE)
779bf215546Sopenharmony_ci      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxCombinedTextureImageUnits;
780bf215546Sopenharmony_ci   if (texunit >= maxUnit) {
781bf215546Sopenharmony_ci      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnviv(texunit=%d)",
782bf215546Sopenharmony_ci                  texunit);
783bf215546Sopenharmony_ci      return;
784bf215546Sopenharmony_ci   }
785bf215546Sopenharmony_ci
786bf215546Sopenharmony_ci   if (target == GL_TEXTURE_ENV) {
787bf215546Sopenharmony_ci      struct gl_fixedfunc_texture_unit *texUnit =
788bf215546Sopenharmony_ci         _mesa_get_fixedfunc_tex_unit(ctx, texunit);
789bf215546Sopenharmony_ci
790bf215546Sopenharmony_ci      /* The GL spec says that we should report an error if the unit is greater
791bf215546Sopenharmony_ci       * than GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, but in practice, only
792bf215546Sopenharmony_ci       * fixed-function units are usable. This is probably a spec bug.
793bf215546Sopenharmony_ci       * Ignore calls for non-fixed-func units, because we don't process
794bf215546Sopenharmony_ci       * glTexEnv for them either.
795bf215546Sopenharmony_ci       */
796bf215546Sopenharmony_ci      if (!texUnit)
797bf215546Sopenharmony_ci         return;
798bf215546Sopenharmony_ci
799bf215546Sopenharmony_ci      if (pname == GL_TEXTURE_ENV_COLOR) {
800bf215546Sopenharmony_ci         params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] );
801bf215546Sopenharmony_ci         params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] );
802bf215546Sopenharmony_ci         params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] );
803bf215546Sopenharmony_ci         params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] );
804bf215546Sopenharmony_ci      }
805bf215546Sopenharmony_ci      else {
806bf215546Sopenharmony_ci         GLint val = get_texenvi(ctx, texUnit, pname);
807bf215546Sopenharmony_ci         if (val >= 0) {
808bf215546Sopenharmony_ci            *params = val;
809bf215546Sopenharmony_ci         }
810bf215546Sopenharmony_ci      }
811bf215546Sopenharmony_ci   }
812bf215546Sopenharmony_ci   else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
813bf215546Sopenharmony_ci      const struct gl_texture_unit *texUnit = _mesa_get_tex_unit(ctx, texunit);
814bf215546Sopenharmony_ci
815bf215546Sopenharmony_ci      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
816bf215546Sopenharmony_ci         *params = (GLint) texUnit->LodBias;
817bf215546Sopenharmony_ci      }
818bf215546Sopenharmony_ci      else {
819bf215546Sopenharmony_ci         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
820bf215546Sopenharmony_ci	 return;
821bf215546Sopenharmony_ci      }
822bf215546Sopenharmony_ci   }
823bf215546Sopenharmony_ci   else if (target == GL_POINT_SPRITE) {
824bf215546Sopenharmony_ci      /* GL_ARB_point_sprite */
825bf215546Sopenharmony_ci      if (!ctx->Extensions.ARB_point_sprite) {
826bf215546Sopenharmony_ci         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
827bf215546Sopenharmony_ci         return;
828bf215546Sopenharmony_ci      }
829bf215546Sopenharmony_ci      if (pname == GL_COORD_REPLACE) {
830bf215546Sopenharmony_ci         if (ctx->Point.CoordReplace & (1u << texunit))
831bf215546Sopenharmony_ci            *params = GL_TRUE;
832bf215546Sopenharmony_ci         else
833bf215546Sopenharmony_ci            *params = GL_FALSE;
834bf215546Sopenharmony_ci      }
835bf215546Sopenharmony_ci      else {
836bf215546Sopenharmony_ci         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
837bf215546Sopenharmony_ci         return;
838bf215546Sopenharmony_ci      }
839bf215546Sopenharmony_ci   }
840bf215546Sopenharmony_ci   else {
841bf215546Sopenharmony_ci      _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
842bf215546Sopenharmony_ci      return;
843bf215546Sopenharmony_ci   }
844bf215546Sopenharmony_ci}
845bf215546Sopenharmony_ci
846bf215546Sopenharmony_ci
847bf215546Sopenharmony_civoid GLAPIENTRY
848bf215546Sopenharmony_ci_mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
849bf215546Sopenharmony_ci{
850bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
851bf215546Sopenharmony_ci   _mesa_gettexenvfv_indexed(ctx->Texture.CurrentUnit, target, pname, params);
852bf215546Sopenharmony_ci}
853bf215546Sopenharmony_ci
854bf215546Sopenharmony_ci
855bf215546Sopenharmony_civoid GLAPIENTRY
856bf215546Sopenharmony_ci_mesa_GetMultiTexEnvfvEXT( GLenum texunit, GLenum target,
857bf215546Sopenharmony_ci                           GLenum pname, GLfloat *params )
858bf215546Sopenharmony_ci{
859bf215546Sopenharmony_ci   _mesa_gettexenvfv_indexed(texunit - GL_TEXTURE0, target, pname, params);
860bf215546Sopenharmony_ci}
861bf215546Sopenharmony_ci
862bf215546Sopenharmony_ci
863bf215546Sopenharmony_civoid GLAPIENTRY
864bf215546Sopenharmony_ci_mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
865bf215546Sopenharmony_ci{
866bf215546Sopenharmony_ci   GET_CURRENT_CONTEXT(ctx);
867bf215546Sopenharmony_ci   _mesa_gettexenviv_indexed(ctx->Texture.CurrentUnit, target, pname, params);
868bf215546Sopenharmony_ci}
869bf215546Sopenharmony_ci
870bf215546Sopenharmony_ci
871bf215546Sopenharmony_civoid GLAPIENTRY
872bf215546Sopenharmony_ci_mesa_GetMultiTexEnvivEXT( GLenum texunit, GLenum target,
873bf215546Sopenharmony_ci                           GLenum pname, GLint *params )
874bf215546Sopenharmony_ci{
875bf215546Sopenharmony_ci   _mesa_gettexenviv_indexed(texunit - GL_TEXTURE0, target, pname, params);
876bf215546Sopenharmony_ci}
877