VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_texdiff.c@ 37277

Last change on this file since 37277 was 34107, checked in by vboxsync, 14 years ago

crOpenGL/wddm: resync shared data only once

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 60.1 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#include "state.h"
8#include "state/cr_statetypes.h"
9#include "state/cr_texture.h"
10#include "cr_hash.h"
11#include "cr_string.h"
12#include "cr_mem.h"
13#include "cr_version.h"
14#include "state_internals.h"
15
16
17#define UNIMPLEMENTED() crStateError(__LINE__,__FILE__,GL_INVALID_OPERATION, "Unimplemented something or other" )
18
19
20#if 0 /* NOT USED??? */
21void crStateTextureObjSwitchCallback( unsigned long key, void *data1, void *data2 )
22{
23 CRTextureObj *tobj = (CRTextureObj *) data1;
24 CRContext *fromCtx = (CRContext *) data2;
25 unsigned int i = 0;
26 unsigned int j = 0;
27 CRbitvalue *bitID = fromCtx->bitid;
28 CRbitvalue nbitID[CR_MAX_BITARRAY];
29
30 for (j=0;j<CR_MAX_BITARRAY;j++)
31 nbitID[j] = ~bitID[j];
32
33 if (!tobj) return;
34
35 FILLDIRTY(tobj->dirty);
36 FILLDIRTY(tobj->imageBit);
37
38 for (i = 0; i < fromCtx->limits.maxTextureUnits; i++)
39 {
40 int j;
41
42 FILLDIRTY(tobj->paramsBit[i]);
43
44 switch (tobj->target)
45 {
46 case GL_TEXTURE_1D:
47 case GL_TEXTURE_2D:
48 for (j = 0; j <= fromCtx->texture.maxLevel; j++)
49 {
50 CRTextureLevel *tl = &(tobj->level[j]);
51 FILLDIRTY(tl->dirty);
52 }
53 break;
54#ifdef CR_OPENGL_VERSION_1_2
55 case GL_TEXTURE_3D:
56#endif
57 for (j = 0; j <= fromCtx->texture.max3DLevel; j++)
58 {
59 CRTextureLevel *tl = &(tobj->level[j]);
60 FILLDIRTY(tl->dirty);
61 }
62 break;
63#ifdef CR_ARB_texture_cube_map
64 case GL_TEXTURE_CUBE_MAP_ARB:
65 for (j = 0; j <= fromCtx->texture.maxCubeMapLevel; j++)
66 {
67 CRTextureLevel *tl;
68 /* Positive X */
69 tl = &(tobj->level[j]);
70 FILLDIRTY(tl->dirty);
71 /* Negative X */
72 tl = &(tobj->negativeXlevel[j]);
73 FILLDIRTY(tl->dirty);
74 /* Positive Y */
75 tl = &(tobj->positiveYlevel[j]);
76 FILLDIRTY(tl->dirty);
77 /* Negative Y */
78 tl = &(tobj->negativeYlevel[j]);
79 FILLDIRTY(tl->dirty);
80 /* Positive Z */
81 tl = &(tobj->positiveZlevel[j]);
82 FILLDIRTY(tl->dirty);
83 /* Negative Z */
84 tl = &(tobj->negativeZlevel[j]);
85 FILLDIRTY(tl->dirty);
86 }
87 break;
88#endif
89 default:
90 UNIMPLEMENTED();
91 }
92 }
93}
94#endif
95
96
97void crStateTextureSwitch( CRTextureBits *tb, CRbitvalue *bitID,
98 CRContext *fromCtx, CRContext *toCtx )
99{
100 CRTextureState *from = &(fromCtx->texture);
101 const CRTextureState *to = &(toCtx->texture);
102 unsigned int i,j;
103 glAble able[2];
104 CRbitvalue nbitID[CR_MAX_BITARRAY];
105 unsigned int activeUnit = (unsigned int) -1;
106
107 for (j=0;j<CR_MAX_BITARRAY;j++)
108 nbitID[j] = ~bitID[j];
109 able[0] = diff_api.Disable;
110 able[1] = diff_api.Enable;
111
112 for (i = 0; i < fromCtx->limits.maxTextureUnits; i++)
113 {
114 if (CHECKDIRTY(tb->enable[i], bitID))
115 {
116 if (activeUnit != i) {
117 diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
118 activeUnit = i;
119 }
120 if (from->unit[i].enabled1D != to->unit[i].enabled1D)
121 {
122 able[to->unit[i].enabled1D](GL_TEXTURE_1D);
123 FILLDIRTY(tb->enable[i]);
124 FILLDIRTY(tb->dirty);
125 }
126 if (from->unit[i].enabled2D != to->unit[i].enabled2D)
127 {
128 able[to->unit[i].enabled2D](GL_TEXTURE_2D);
129 FILLDIRTY(tb->enable[i]);
130 FILLDIRTY(tb->dirty);
131 }
132#ifdef CR_OPENGL_VERSION_1_2
133 if (from->unit[i].enabled3D != to->unit[i].enabled3D)
134 {
135 able[to->unit[i].enabled3D](GL_TEXTURE_3D);
136 FILLDIRTY(tb->enable[i]);
137 FILLDIRTY(tb->dirty);
138 }
139#endif
140#ifdef CR_ARB_texture_cube_map
141 if (fromCtx->extensions.ARB_texture_cube_map &&
142 from->unit[i].enabledCubeMap != to->unit[i].enabledCubeMap)
143 {
144 able[to->unit[i].enabledCubeMap](GL_TEXTURE_CUBE_MAP_ARB);
145 FILLDIRTY(tb->enable[i]);
146 FILLDIRTY(tb->dirty);
147 }
148#endif
149#ifdef CR_NV_texture_rectangle
150 if (fromCtx->extensions.NV_texture_rectangle &&
151 from->unit[i].enabledRect != to->unit[i].enabledRect)
152 {
153 able[to->unit[i].enabledRect](GL_TEXTURE_RECTANGLE_NV);
154 FILLDIRTY(tb->enable[i]);
155 FILLDIRTY(tb->dirty);
156 }
157#endif
158 if (from->unit[i].textureGen.s != to->unit[i].textureGen.s ||
159 from->unit[i].textureGen.t != to->unit[i].textureGen.t ||
160 from->unit[i].textureGen.r != to->unit[i].textureGen.r ||
161 from->unit[i].textureGen.q != to->unit[i].textureGen.q)
162 {
163 able[to->unit[i].textureGen.s](GL_TEXTURE_GEN_S);
164 able[to->unit[i].textureGen.t](GL_TEXTURE_GEN_T);
165 able[to->unit[i].textureGen.r](GL_TEXTURE_GEN_R);
166 able[to->unit[i].textureGen.q](GL_TEXTURE_GEN_Q);
167 FILLDIRTY(tb->enable[i]);
168 FILLDIRTY(tb->dirty);
169 }
170 CLEARDIRTY(tb->enable[i], nbitID);
171 }
172
173 /*
174 ** A thought on switching with textures:
175 ** Since we are only performing a switch
176 ** and not a sync, we won't need to
177 ** update individual textures, just
178 ** the bindings....
179 */
180
181 if (CHECKDIRTY(tb->current[i], bitID))
182 {
183 if (activeUnit != i) {
184 diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
185 activeUnit = i;
186 }
187 if (from->unit[i].currentTexture1D->hwid != to->unit[i].currentTexture1D->hwid)
188 {
189 diff_api.BindTexture(GL_TEXTURE_1D, crStateGetTextureObjHWID(to->unit[i].currentTexture1D));
190 FILLDIRTY(tb->current[i]);
191 FILLDIRTY(tb->dirty);
192 }
193 if (from->unit[i].currentTexture2D->hwid != to->unit[i].currentTexture2D->hwid)
194 {
195 diff_api.BindTexture(GL_TEXTURE_2D, crStateGetTextureObjHWID(to->unit[i].currentTexture2D));
196 FILLDIRTY(tb->current[i]);
197 FILLDIRTY(tb->dirty);
198 }
199#ifdef CR_OPENGL_VERSION_1_2
200 if (from->unit[i].currentTexture3D->hwid != to->unit[i].currentTexture3D->hwid)
201 {
202 diff_api.BindTexture(GL_TEXTURE_3D, crStateGetTextureObjHWID(to->unit[i].currentTexture3D));
203 FILLDIRTY(tb->current[i]);
204 FILLDIRTY(tb->dirty);
205 }
206#endif
207#ifdef CR_ARB_texture_cube_map
208 if (fromCtx->extensions.ARB_texture_cube_map &&
209 from->unit[i].currentTextureCubeMap->hwid != to->unit[i].currentTextureCubeMap->hwid)
210 {
211 diff_api.BindTexture(GL_TEXTURE_CUBE_MAP_ARB, crStateGetTextureObjHWID(to->unit[i].currentTextureCubeMap));
212 FILLDIRTY(tb->current[i]);
213 FILLDIRTY(tb->dirty);
214 }
215#endif
216#ifdef CR_NV_texture_rectangle
217 if (fromCtx->extensions.NV_texture_rectangle &&
218 from->unit[i].currentTextureRect->hwid != to->unit[i].currentTextureRect->hwid)
219 {
220 diff_api.BindTexture(GL_TEXTURE_RECTANGLE_NV, crStateGetTextureObjHWID(to->unit[i].currentTextureRect));
221 FILLDIRTY(tb->current[i]);
222 FILLDIRTY(tb->dirty);
223 }
224#endif
225 CLEARDIRTY(tb->current[i], nbitID);
226 }
227
228 if (CHECKDIRTY(tb->objGen[i], bitID))
229 {
230 if (activeUnit != i) {
231 diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
232 activeUnit = i;
233 }
234 if (from->unit[i].objSCoeff.x != to->unit[i].objSCoeff.x ||
235 from->unit[i].objSCoeff.y != to->unit[i].objSCoeff.y ||
236 from->unit[i].objSCoeff.z != to->unit[i].objSCoeff.z ||
237 from->unit[i].objSCoeff.w != to->unit[i].objSCoeff.w)
238 {
239 GLfloat f[4];
240 f[0] = to->unit[i].objSCoeff.x;
241 f[1] = to->unit[i].objSCoeff.y;
242 f[2] = to->unit[i].objSCoeff.z;
243 f[3] = to->unit[i].objSCoeff.w;
244 diff_api.TexGenfv (GL_S, GL_OBJECT_PLANE, (const GLfloat *) f);
245 FILLDIRTY(tb->objGen[i]);
246 FILLDIRTY(tb->dirty);
247 }
248 if (from->unit[i].objTCoeff.x != to->unit[i].objTCoeff.x ||
249 from->unit[i].objTCoeff.y != to->unit[i].objTCoeff.y ||
250 from->unit[i].objTCoeff.z != to->unit[i].objTCoeff.z ||
251 from->unit[i].objTCoeff.w != to->unit[i].objTCoeff.w) {
252 GLfloat f[4];
253 f[0] = to->unit[i].objTCoeff.x;
254 f[1] = to->unit[i].objTCoeff.y;
255 f[2] = to->unit[i].objTCoeff.z;
256 f[3] = to->unit[i].objTCoeff.w;
257 diff_api.TexGenfv (GL_T, GL_OBJECT_PLANE, (const GLfloat *) f);
258 FILLDIRTY(tb->objGen[i]);
259 FILLDIRTY(tb->dirty);
260 }
261 if (from->unit[i].objRCoeff.x != to->unit[i].objRCoeff.x ||
262 from->unit[i].objRCoeff.y != to->unit[i].objRCoeff.y ||
263 from->unit[i].objRCoeff.z != to->unit[i].objRCoeff.z ||
264 from->unit[i].objRCoeff.w != to->unit[i].objRCoeff.w) {
265 GLfloat f[4];
266 f[0] = to->unit[i].objRCoeff.x;
267 f[1] = to->unit[i].objRCoeff.y;
268 f[2] = to->unit[i].objRCoeff.z;
269 f[3] = to->unit[i].objRCoeff.w;
270 diff_api.TexGenfv (GL_R, GL_OBJECT_PLANE, (const GLfloat *) f);
271 FILLDIRTY(tb->objGen[i]);
272 FILLDIRTY(tb->dirty);
273 }
274 if (from->unit[i].objQCoeff.x != to->unit[i].objQCoeff.x ||
275 from->unit[i].objQCoeff.y != to->unit[i].objQCoeff.y ||
276 from->unit[i].objQCoeff.z != to->unit[i].objQCoeff.z ||
277 from->unit[i].objQCoeff.w != to->unit[i].objQCoeff.w) {
278 GLfloat f[4];
279 f[0] = to->unit[i].objQCoeff.x;
280 f[1] = to->unit[i].objQCoeff.y;
281 f[2] = to->unit[i].objQCoeff.z;
282 f[3] = to->unit[i].objQCoeff.w;
283 diff_api.TexGenfv (GL_Q, GL_OBJECT_PLANE, (const GLfloat *) f);
284 FILLDIRTY(tb->objGen[i]);
285 FILLDIRTY(tb->dirty);
286 }
287 CLEARDIRTY(tb->objGen[i], nbitID);
288 }
289 if (CHECKDIRTY(tb->eyeGen[i], bitID))
290 {
291 if (activeUnit != i) {
292 diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
293 activeUnit = i;
294 }
295 diff_api.MatrixMode(GL_MODELVIEW);
296 diff_api.PushMatrix();
297 diff_api.LoadIdentity();
298 if (from->unit[i].eyeSCoeff.x != to->unit[i].eyeSCoeff.x ||
299 from->unit[i].eyeSCoeff.y != to->unit[i].eyeSCoeff.y ||
300 from->unit[i].eyeSCoeff.z != to->unit[i].eyeSCoeff.z ||
301 from->unit[i].eyeSCoeff.w != to->unit[i].eyeSCoeff.w) {
302 GLfloat f[4];
303 f[0] = to->unit[i].eyeSCoeff.x;
304 f[1] = to->unit[i].eyeSCoeff.y;
305 f[2] = to->unit[i].eyeSCoeff.z;
306 f[3] = to->unit[i].eyeSCoeff.w;
307 diff_api.TexGenfv (GL_S, GL_EYE_PLANE, (const GLfloat *) f);
308 FILLDIRTY(tb->eyeGen[i]);
309 FILLDIRTY(tb->dirty);
310 }
311 if (from->unit[i].eyeTCoeff.x != to->unit[i].eyeTCoeff.x ||
312 from->unit[i].eyeTCoeff.y != to->unit[i].eyeTCoeff.y ||
313 from->unit[i].eyeTCoeff.z != to->unit[i].eyeTCoeff.z ||
314 from->unit[i].eyeTCoeff.w != to->unit[i].eyeTCoeff.w) {
315 GLfloat f[4];
316 f[0] = to->unit[i].eyeTCoeff.x;
317 f[1] = to->unit[i].eyeTCoeff.y;
318 f[2] = to->unit[i].eyeTCoeff.z;
319 f[3] = to->unit[i].eyeTCoeff.w;
320 diff_api.TexGenfv (GL_T, GL_EYE_PLANE, (const GLfloat *) f);
321 FILLDIRTY(tb->eyeGen[i]);
322 FILLDIRTY(tb->dirty);
323 }
324 if (from->unit[i].eyeRCoeff.x != to->unit[i].eyeRCoeff.x ||
325 from->unit[i].eyeRCoeff.y != to->unit[i].eyeRCoeff.y ||
326 from->unit[i].eyeRCoeff.z != to->unit[i].eyeRCoeff.z ||
327 from->unit[i].eyeRCoeff.w != to->unit[i].eyeRCoeff.w) {
328 GLfloat f[4];
329 f[0] = to->unit[i].eyeRCoeff.x;
330 f[1] = to->unit[i].eyeRCoeff.y;
331 f[2] = to->unit[i].eyeRCoeff.z;
332 f[3] = to->unit[i].eyeRCoeff.w;
333 diff_api.TexGenfv (GL_R, GL_EYE_PLANE, (const GLfloat *) f);
334 FILLDIRTY(tb->eyeGen[i]);
335 FILLDIRTY(tb->dirty);
336 }
337 if (from->unit[i].eyeQCoeff.x != to->unit[i].eyeQCoeff.x ||
338 from->unit[i].eyeQCoeff.y != to->unit[i].eyeQCoeff.y ||
339 from->unit[i].eyeQCoeff.z != to->unit[i].eyeQCoeff.z ||
340 from->unit[i].eyeQCoeff.w != to->unit[i].eyeQCoeff.w) {
341 GLfloat f[4];
342 f[0] = to->unit[i].eyeQCoeff.x;
343 f[1] = to->unit[i].eyeQCoeff.y;
344 f[2] = to->unit[i].eyeQCoeff.z;
345 f[3] = to->unit[i].eyeQCoeff.w;
346 diff_api.TexGenfv (GL_Q, GL_EYE_PLANE, (const GLfloat *) f);
347 FILLDIRTY(tb->eyeGen[i]);
348 FILLDIRTY(tb->dirty);
349 }
350 diff_api.PopMatrix();
351 CLEARDIRTY(tb->eyeGen[i], nbitID);
352 }
353 if (CHECKDIRTY(tb->genMode[i], bitID))
354 {
355 if (activeUnit != i) {
356 diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
357 activeUnit = i;
358 }
359 if (from->unit[i].gen.s != to->unit[i].gen.s ||
360 from->unit[i].gen.t != to->unit[i].gen.t ||
361 from->unit[i].gen.r != to->unit[i].gen.r ||
362 from->unit[i].gen.q != to->unit[i].gen.q)
363 {
364 diff_api.TexGeni (GL_S, GL_TEXTURE_GEN_MODE, to->unit[i].gen.s);
365 diff_api.TexGeni (GL_T, GL_TEXTURE_GEN_MODE, to->unit[i].gen.t);
366 diff_api.TexGeni (GL_R, GL_TEXTURE_GEN_MODE, to->unit[i].gen.r);
367 diff_api.TexGeni (GL_Q, GL_TEXTURE_GEN_MODE, to->unit[i].gen.q);
368 FILLDIRTY(tb->genMode[i]);
369 FILLDIRTY(tb->dirty);
370 }
371 CLEARDIRTY(tb->genMode[i], nbitID);
372 }
373 CLEARDIRTY(tb->dirty, nbitID);
374
375 /* Texture enviroment */
376 if (CHECKDIRTY(tb->envBit[i], bitID))
377 {
378 if (activeUnit != i) {
379 diff_api.ActiveTextureARB( i + GL_TEXTURE0_ARB );
380 activeUnit = i;
381 }
382 if (from->unit[i].envMode != to->unit[i].envMode)
383 {
384 diff_api.TexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, to->unit[i].envMode);
385 FILLDIRTY(tb->envBit[i]);
386 FILLDIRTY(tb->dirty);
387 }
388 if (from->unit[i].envColor.r != to->unit[i].envColor.r ||
389 from->unit[i].envColor.g != to->unit[i].envColor.g ||
390 from->unit[i].envColor.b != to->unit[i].envColor.b ||
391 from->unit[i].envColor.a != to->unit[i].envColor.a)
392 {
393 GLfloat f[4];
394 f[0] = to->unit[i].envColor.r;
395 f[1] = to->unit[i].envColor.g;
396 f[2] = to->unit[i].envColor.b;
397 f[3] = to->unit[i].envColor.a;
398 diff_api.TexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const GLfloat *) f);
399 FILLDIRTY(tb->envBit[i]);
400 FILLDIRTY(tb->dirty);
401 }
402 if (from->unit[i].combineModeRGB != to->unit[i].combineModeRGB)
403 {
404 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, to->unit[i].combineModeRGB);
405 FILLDIRTY(tb->envBit[i]);
406 FILLDIRTY(tb->dirty);
407 }
408 if (from->unit[i].combineModeA != to->unit[i].combineModeA)
409 {
410 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, to->unit[i].combineModeA);
411 FILLDIRTY(tb->envBit[i]);
412 FILLDIRTY(tb->dirty);
413 }
414 if (from->unit[i].combineSourceRGB[0] != to->unit[i].combineSourceRGB[0])
415 {
416 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, to->unit[i].combineSourceRGB[0]);
417 FILLDIRTY(tb->envBit[i]);
418 FILLDIRTY(tb->dirty);
419 }
420 if (from->unit[i].combineSourceRGB[1] != to->unit[i].combineSourceRGB[1])
421 {
422 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, to->unit[i].combineSourceRGB[1]);
423 FILLDIRTY(tb->envBit[i]);
424 FILLDIRTY(tb->dirty);
425 }
426 if (from->unit[i].combineSourceRGB[2] != to->unit[i].combineSourceRGB[2])
427 {
428 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, to->unit[i].combineSourceRGB[2]);
429 FILLDIRTY(tb->envBit[i]);
430 FILLDIRTY(tb->dirty);
431 }
432 if (from->unit[i].combineSourceA[0] != to->unit[i].combineSourceA[0])
433 {
434 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, to->unit[i].combineSourceA[0]);
435 FILLDIRTY(tb->envBit[i]);
436 FILLDIRTY(tb->dirty);
437 }
438 if (from->unit[i].combineSourceA[1] != to->unit[i].combineSourceA[1])
439 {
440 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, to->unit[i].combineSourceA[1]);
441 FILLDIRTY(tb->envBit[i]);
442 FILLDIRTY(tb->dirty);
443 }
444 if (from->unit[i].combineSourceA[2] != to->unit[i].combineSourceA[2])
445 {
446 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, to->unit[i].combineSourceA[2]);
447 FILLDIRTY(tb->envBit[i]);
448 FILLDIRTY(tb->dirty);
449 }
450 if (from->unit[i].combineOperandRGB[0] != to->unit[i].combineOperandRGB[0])
451 {
452 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, to->unit[i].combineOperandRGB[0]);
453 FILLDIRTY(tb->envBit[i]);
454 FILLDIRTY(tb->dirty);
455 }
456 if (from->unit[i].combineOperandRGB[1] != to->unit[i].combineOperandRGB[1])
457 {
458 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, to->unit[i].combineOperandRGB[1]);
459 FILLDIRTY(tb->envBit[i]);
460 FILLDIRTY(tb->dirty);
461 }
462 if (from->unit[i].combineOperandRGB[2] != to->unit[i].combineOperandRGB[2])
463 {
464 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, to->unit[i].combineOperandRGB[2]);
465 FILLDIRTY(tb->envBit[i]);
466 FILLDIRTY(tb->dirty);
467 }
468 if (from->unit[i].combineOperandA[0] != to->unit[i].combineOperandA[0])
469 {
470 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, to->unit[i].combineOperandA[0]);
471 FILLDIRTY(tb->envBit[i]);
472 FILLDIRTY(tb->dirty);
473 }
474 if (from->unit[i].combineOperandA[1] != to->unit[i].combineOperandA[1])
475 {
476 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, to->unit[i].combineOperandA[1]);
477 FILLDIRTY(tb->envBit[i]);
478 FILLDIRTY(tb->dirty);
479 }
480 if (from->unit[i].combineOperandA[2] != to->unit[i].combineOperandA[2])
481 {
482 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, to->unit[i].combineOperandA[2]);
483 FILLDIRTY(tb->envBit[i]);
484 FILLDIRTY(tb->dirty);
485 }
486 if (from->unit[i].combineScaleRGB != to->unit[i].combineScaleRGB)
487 {
488 diff_api.TexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, to->unit[i].combineScaleRGB);
489 FILLDIRTY(tb->envBit[i]);
490 FILLDIRTY(tb->dirty);
491 }
492 if (from->unit[i].combineScaleA != to->unit[i].combineScaleA)
493 {
494 diff_api.TexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, to->unit[i].combineScaleA);
495 FILLDIRTY(tb->envBit[i]);
496 FILLDIRTY(tb->dirty);
497 }
498 CLEARDIRTY(tb->envBit[i], nbitID);
499 }
500 }
501
502 /* Resend texture images */
503 if (toCtx->shared->bTexResyncNeeded)
504 {
505 toCtx->shared->bTexResyncNeeded = GL_FALSE;
506
507 crStateDiffAllTextureObjects(toCtx, bitID, GL_TRUE);
508 }
509
510 /* After possible fiddling put them back now */
511 if (activeUnit != toCtx->texture.curTextureUnit) {
512 diff_api.ActiveTextureARB( toCtx->texture.curTextureUnit + GL_TEXTURE0_ARB );
513 }
514 diff_api.MatrixMode(toCtx->transform.matrixMode);
515}
516
517
518/*
519 * Check the dirty bits for the specified texture on a given unit to
520 * determine if any of its images are dirty.
521 * Return: 1 -- dirty, 0 -- clean
522 */
523int crStateTextureCheckDirtyImages(CRContext *from, CRContext *to, GLenum target, int textureUnit)
524{
525 CRContext *g = GetCurrentContext();
526 CRTextureState *tsto;
527 CRbitvalue *bitID;
528 CRTextureObj *tobj = NULL;
529 int maxLevel = 0, i;
530 int face, numFaces;
531
532 CRASSERT(to);
533 CRASSERT(from);
534
535 tsto = &(to->texture);
536 bitID = from->bitid;
537
538 CRASSERT(tsto);
539
540 switch(target)
541 {
542 case GL_TEXTURE_1D:
543 tobj = tsto->unit[textureUnit].currentTexture1D;
544 maxLevel = tsto->maxLevel;
545 break;
546 case GL_TEXTURE_2D:
547 tobj = tsto->unit[textureUnit].currentTexture2D;
548 maxLevel = tsto->maxLevel;
549 break;
550#ifdef CR_OPENGL_VERSION_1_2
551 case GL_TEXTURE_3D:
552 tobj = tsto->unit[textureUnit].currentTexture3D;
553 maxLevel = tsto->max3DLevel;
554 break;
555#endif
556#ifdef CR_ARB_texture_cube_map
557 case GL_TEXTURE_CUBE_MAP:
558 if (g->extensions.ARB_texture_cube_map) {
559 tobj = tsto->unit[textureUnit].currentTextureCubeMap;
560 maxLevel = tsto->maxCubeMapLevel;
561 }
562 break;
563#endif
564#ifdef CR_NV_texture_rectangle
565 case GL_TEXTURE_RECTANGLE_NV:
566 if (g->extensions.NV_texture_rectangle) {
567 tobj = tsto->unit[textureUnit].currentTextureRect;
568 maxLevel = 1;
569 }
570 break;
571#endif
572 default:
573 crError("Bad texture target in crStateTextureCheckDirtyImages()");
574 return 0;
575 }
576
577 if (!tobj)
578 {
579 return 0;
580 }
581
582 numFaces = (target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
583
584 for (face = 0; face < numFaces; face++) {
585 for (i = 0; i < maxLevel; i++) {
586 if (CHECKDIRTY(tobj->level[face][i].dirty, bitID))
587 return 1;
588 }
589 }
590
591 return 0;
592}
593
594
595/*
596 * Do texture state differencing for the given texture object.
597 */
598void
599crStateTextureObjectDiff(CRContext *fromCtx,
600 const CRbitvalue *bitID, const CRbitvalue *nbitID,
601 CRTextureObj *tobj, GLboolean alwaysDirty)
602{
603 CRTextureState *from = &(fromCtx->texture);
604 glAble able[2];
605 int u = 0; /* always use texture unit 0 for diff'ing */
606
607 able[0] = diff_api.Disable;
608 able[1] = diff_api.Enable;
609
610#if 0
611 /* XXX disabling this code fixed Wes Bethel's problem with missing/white
612 * textures. Setting the active texture unit here can screw up the
613 * current texture object bindings.
614 */
615 /* Set active texture unit, and bind this texture object */
616 if (from->curTextureUnit != u) {
617 diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
618 from->curTextureUnit = u;
619 }
620#endif
621
622 diff_api.BindTexture(tobj->target, crStateGetTextureObjHWID(tobj));
623
624 if (alwaysDirty || CHECKDIRTY(tobj->paramsBit[u], bitID))
625 {
626 GLfloat f[4];
627 f[0] = tobj->borderColor.r;
628 f[1] = tobj->borderColor.g;
629 f[2] = tobj->borderColor.b;
630 f[3] = tobj->borderColor.a;
631 diff_api.TexParameteri(tobj->target, GL_TEXTURE_BASE_LEVEL, tobj->baseLevel);
632 diff_api.TexParameteri(tobj->target, GL_TEXTURE_MAX_LEVEL, tobj->maxLevel);
633 diff_api.TexParameteri(tobj->target, GL_TEXTURE_MIN_FILTER, tobj->minFilter);
634 diff_api.TexParameteri(tobj->target, GL_TEXTURE_MAG_FILTER, tobj->magFilter);
635 diff_api.TexParameteri(tobj->target, GL_TEXTURE_WRAP_S, tobj->wrapS);
636 diff_api.TexParameteri(tobj->target, GL_TEXTURE_WRAP_T, tobj->wrapT);
637#ifdef CR_OPENGL_VERSION_1_2
638 diff_api.TexParameteri(tobj->target, GL_TEXTURE_WRAP_R, tobj->wrapR);
639 diff_api.TexParameterf(tobj->target, GL_TEXTURE_PRIORITY, tobj->priority);
640#endif
641 diff_api.TexParameterfv(tobj->target, GL_TEXTURE_BORDER_COLOR, (const GLfloat *) f);
642#ifdef CR_EXT_texture_filter_anisotropic
643 if (fromCtx->extensions.EXT_texture_filter_anisotropic) {
644 diff_api.TexParameterf(tobj->target, GL_TEXTURE_MAX_ANISOTROPY_EXT, tobj->maxAnisotropy);
645 }
646#endif
647#ifdef CR_ARB_depth_texture
648 if (fromCtx->extensions.ARB_depth_texture)
649 diff_api.TexParameteri(tobj->target, GL_DEPTH_TEXTURE_MODE_ARB, tobj->depthMode);
650#endif
651#ifdef CR_ARB_shadow
652 if (fromCtx->extensions.ARB_shadow) {
653 diff_api.TexParameteri(tobj->target, GL_TEXTURE_COMPARE_MODE_ARB, tobj->compareMode);
654 diff_api.TexParameteri(tobj->target, GL_TEXTURE_COMPARE_FUNC_ARB, tobj->compareFunc);
655 }
656#endif
657#ifdef CR_ARB_shadow_ambient
658 if (fromCtx->extensions.ARB_shadow_ambient) {
659 diff_api.TexParameterf(tobj->target, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, tobj->compareFailValue);
660 }
661#endif
662#ifdef CR_SGIS_generate_mipmap
663 if (fromCtx->extensions.SGIS_generate_mipmap) {
664 diff_api.TexParameteri(tobj->target, GL_GENERATE_MIPMAP_SGIS, tobj->generateMipmap);
665 }
666#endif
667 if (!alwaysDirty)
668 CLEARDIRTY(tobj->paramsBit[u], nbitID);
669 }
670
671 /* now, if the texture images are dirty */
672 if (alwaysDirty || CHECKDIRTY(tobj->imageBit, bitID))
673 {
674 int lvl;
675 int face;
676
677 switch (tobj->target)
678 {
679 case GL_TEXTURE_1D:
680 for (lvl = 0; lvl <= from->maxLevel; lvl++)
681 {
682 CRTextureLevel *tl = &(tobj->level[0][lvl]);
683 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
684 {
685 if (tl->generateMipmap) {
686 diff_api.TexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, 1);
687 }
688 if (tl->compressed) {
689 diff_api.CompressedTexImage1DARB(GL_TEXTURE_1D, lvl,
690 tl->internalFormat, tl->width,
691 tl->border, tl->bytes, tl->img);
692 }
693 else {
694 /* alignment must be one */
695 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
696 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
697 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
698 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
699 if (tl->generateMipmap) {
700 diff_api.TexParameteri(GL_TEXTURE_1D, GL_GENERATE_MIPMAP_SGIS, 1);
701 }
702 diff_api.TexImage1D(GL_TEXTURE_1D, lvl,
703 tl->internalFormat,
704 tl->width, tl->border,
705 tl->format, tl->type, tl->img);
706 }
707 if (!alwaysDirty)
708 {
709 CLEARDIRTY(tl->dirty, nbitID);
710 }
711#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
712 else
713 {
714 crFree(tl->img);
715 tl->img = NULL;
716 }
717#endif
718 }
719 }
720 break;
721 case GL_TEXTURE_2D:
722 for (lvl = 0; lvl <= from->maxLevel; lvl++)
723 {
724 CRTextureLevel *tl = &(tobj->level[0][lvl]);
725 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
726 {
727 if (tl->generateMipmap) {
728 diff_api.TexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, 1);
729 }
730
731 if (tl->compressed) {
732 diff_api.CompressedTexImage2DARB(GL_TEXTURE_2D, lvl,
733 tl->internalFormat, tl->width,
734 tl->height, tl->border,
735 tl->bytes, tl->img);
736 }
737 else {
738 /* alignment must be one */
739 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
740 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
741 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
742 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
743 diff_api.TexImage2D(GL_TEXTURE_2D, lvl,
744 tl->internalFormat,
745 tl->width, tl->height, tl->border,
746 tl->format, tl->type, tl->img);
747 }
748
749 if (!alwaysDirty)
750 {
751 CLEARDIRTY(tl->dirty, nbitID);
752 }
753#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
754 else
755 {
756 crFree(tl->img);
757 tl->img = NULL;
758 }
759#endif
760 }
761 }
762 break;
763#ifdef CR_OPENGL_VERSION_1_2
764 case GL_TEXTURE_3D:
765 for (lvl = 0; lvl <= from->max3DLevel; lvl++)
766 {
767 CRTextureLevel *tl = &(tobj->level[0][lvl]);
768 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
769 {
770 if (tl->generateMipmap) {
771 diff_api.TexParameteri(GL_TEXTURE_3D, GL_GENERATE_MIPMAP_SGIS, 1);
772 }
773 if (tl->compressed) {
774 diff_api.CompressedTexImage3DARB(GL_TEXTURE_3D, lvl,
775 tl->internalFormat, tl->width,
776 tl->height, tl->depth,
777 tl->border, tl->bytes, tl->img);
778 }
779 else {
780 /* alignment must be one */
781 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
782 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
783 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
784 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
785 diff_api.TexImage3D(GL_TEXTURE_3D, lvl,
786 tl->internalFormat,
787 tl->width, tl->height, tl->depth,
788 tl->border, tl->format,
789 tl->type, tl->img);
790 }
791 if (!alwaysDirty)
792 {
793 CLEARDIRTY(tl->dirty, nbitID);
794 }
795#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
796 else
797 {
798 crFree(tl->img);
799 tl->img = NULL;
800 }
801#endif
802 }
803 }
804 break;
805#endif
806#ifdef CR_NV_texture_rectangle
807 case GL_TEXTURE_RECTANGLE_NV:
808 /* only one level */
809 for (lvl = 0; lvl <= from->maxRectLevel; lvl++)
810 {
811 CRTextureLevel *tl = &(tobj->level[0][lvl]);
812 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
813 {
814 if (tl->compressed) {
815 diff_api.CompressedTexImage2DARB(GL_TEXTURE_RECTANGLE_NV, lvl,
816 tl->internalFormat, tl->width,
817 tl->height, tl->border,
818 tl->bytes, tl->img);
819 }
820 else {
821 /* alignment must be one */
822 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
823 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
824 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
825 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
826 diff_api.TexImage2D(GL_TEXTURE_RECTANGLE_NV, lvl,
827 tl->internalFormat,
828 tl->width, tl->height, tl->border,
829 tl->format, tl->type, tl->img);
830 }
831 if (!alwaysDirty)
832 {
833 CLEARDIRTY(tl->dirty, nbitID);
834 }
835#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
836 else
837 {
838 crFree(tl->img);
839 tl->img = NULL;
840 }
841#endif
842 }
843 }
844 break;
845#endif
846#ifdef CR_ARB_texture_cube_map
847 case GL_TEXTURE_CUBE_MAP_ARB:
848 for (face = 0; face < 6; face++)
849 {
850 const GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
851 for (lvl = 0; lvl <= from->maxCubeMapLevel; lvl++)
852 {
853 CRTextureLevel *tl = &(tobj->level[face][lvl]);
854 if (alwaysDirty || CHECKDIRTY(tl->dirty, bitID))
855 {
856 if (tl->generateMipmap) {
857 diff_api.TexParameteri(GL_TEXTURE_CUBE_MAP_ARB,
858 GL_GENERATE_MIPMAP_SGIS, 1);
859 }
860 if (tl->compressed) {
861 diff_api.CompressedTexImage2DARB(target,
862 lvl, tl->internalFormat,
863 tl->width, tl->height,
864 tl->border, tl->bytes, tl->img);
865 }
866 else {
867 /* alignment must be one */
868 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
869 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
870 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, 0);
871 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
872 diff_api.TexImage2D(target, lvl,
873 tl->internalFormat,
874 tl->width, tl->height, tl->border,
875 tl->format, tl->type, tl->img);
876 }
877 if (!alwaysDirty)
878 {
879 CLEARDIRTY(tl->dirty, nbitID);
880 }
881#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
882 else
883 {
884 crFree(tl->img);
885 tl->img = NULL;
886 }
887#endif
888 }
889 } /* for lvl */
890 } /* for face */
891 break;
892#endif
893 default:
894 UNIMPLEMENTED();
895
896 } /* switch */
897 } /* if (CHECKDIRTY(tobj->imageBit, bitID)) */
898}
899
900
901
902void
903crStateTextureDiff( CRTextureBits *tb, CRbitvalue *bitID,
904 CRContext *fromCtx, CRContext *toCtx )
905{
906 CRTextureState *from = &(fromCtx->texture);
907 CRTextureState *to = &(toCtx->texture);
908 unsigned int u, t, j;
909 glAble able[2];
910 CRbitvalue nbitID[CR_MAX_BITARRAY];
911 const GLboolean haveFragProg = fromCtx->extensions.ARB_fragment_program || fromCtx->extensions.NV_fragment_program;
912
913 for (j=0;j<CR_MAX_BITARRAY;j++)
914 nbitID[j] = ~bitID[j];
915
916 able[0] = diff_api.Disable;
917 able[1] = diff_api.Enable;
918
919 /* loop over texture units */
920 for (u = 0; u < fromCtx->limits.maxTextureUnits; u++)
921 {
922 CRTextureObj **fromBinding = NULL;
923 CRTextureObj *tobj;
924
925 /* take care of enables/disables */
926 if (CHECKDIRTY(tb->enable[u], bitID))
927 {
928
929 /* Activate texture unit u if needed */
930 if (fromCtx->texture.curTextureUnit != u) {
931 diff_api.ActiveTextureARB( GL_TEXTURE0_ARB + u);
932 fromCtx->texture.curTextureUnit = u;
933 }
934
935 if (from->unit[u].enabled1D != to->unit[u].enabled1D)
936 {
937 able[to->unit[u].enabled1D](GL_TEXTURE_1D);
938 from->unit[u].enabled1D = to->unit[u].enabled1D;
939 }
940 if (from->unit[u].enabled2D != to->unit[u].enabled2D)
941 {
942 able[to->unit[u].enabled2D](GL_TEXTURE_2D);
943 from->unit[u].enabled2D = to->unit[u].enabled2D;
944 }
945#ifdef CR_OPENGL_VERSION_1_2
946 if (from->unit[u].enabled3D != to->unit[u].enabled3D)
947 {
948 able[to->unit[u].enabled3D](GL_TEXTURE_3D);
949 from->unit[u].enabled3D = to->unit[u].enabled3D;
950 }
951#endif
952#ifdef CR_ARB_texture_cube_map
953 if (fromCtx->extensions.ARB_texture_cube_map &&
954 from->unit[u].enabledCubeMap != to->unit[u].enabledCubeMap)
955 {
956 able[to->unit[u].enabledCubeMap](GL_TEXTURE_CUBE_MAP_ARB);
957 from->unit[u].enabledCubeMap = to->unit[u].enabledCubeMap;
958 }
959#endif
960#ifdef CR_NV_texture_rectangle
961 if (fromCtx->extensions.NV_texture_rectangle &&
962 from->unit[u].enabledRect != to->unit[u].enabledRect)
963 {
964 able[to->unit[u].enabledRect](GL_TEXTURE_RECTANGLE_NV);
965 from->unit[u].enabledRect = to->unit[u].enabledRect;
966 }
967#endif
968
969 /* texgen enables */
970 if (from->unit[u].textureGen.s != to->unit[u].textureGen.s ||
971 from->unit[u].textureGen.t != to->unit[u].textureGen.t ||
972 from->unit[u].textureGen.r != to->unit[u].textureGen.r ||
973 from->unit[u].textureGen.q != to->unit[u].textureGen.q)
974 {
975 able[to->unit[u].textureGen.s](GL_TEXTURE_GEN_S);
976 able[to->unit[u].textureGen.t](GL_TEXTURE_GEN_T);
977 able[to->unit[u].textureGen.r](GL_TEXTURE_GEN_R);
978 able[to->unit[u].textureGen.q](GL_TEXTURE_GEN_Q);
979 from->unit[u].textureGen = to->unit[u].textureGen;
980 }
981 CLEARDIRTY(tb->enable[u], nbitID);
982 }
983
984
985 /* Texgen coefficients */
986 if (CHECKDIRTY(tb->objGen[u], bitID))
987 {
988 if (fromCtx->texture.curTextureUnit != u) {
989 diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
990 fromCtx->texture.curTextureUnit = u;
991 }
992 if (from->unit[u].objSCoeff.x != to->unit[u].objSCoeff.x ||
993 from->unit[u].objSCoeff.y != to->unit[u].objSCoeff.y ||
994 from->unit[u].objSCoeff.z != to->unit[u].objSCoeff.z ||
995 from->unit[u].objSCoeff.w != to->unit[u].objSCoeff.w)
996 {
997 GLfloat f[4];
998 f[0] = to->unit[u].objSCoeff.x;
999 f[1] = to->unit[u].objSCoeff.y;
1000 f[2] = to->unit[u].objSCoeff.z;
1001 f[3] = to->unit[u].objSCoeff.w;
1002 diff_api.TexGenfv (GL_S, GL_OBJECT_PLANE, (const GLfloat *) f);
1003 from->unit[u].objSCoeff = to->unit[u].objSCoeff;
1004 }
1005 if (from->unit[u].objTCoeff.x != to->unit[u].objTCoeff.x ||
1006 from->unit[u].objTCoeff.y != to->unit[u].objTCoeff.y ||
1007 from->unit[u].objTCoeff.z != to->unit[u].objTCoeff.z ||
1008 from->unit[u].objTCoeff.w != to->unit[u].objTCoeff.w)
1009 {
1010 GLfloat f[4];
1011 f[0] = to->unit[u].objTCoeff.x;
1012 f[1] = to->unit[u].objTCoeff.y;
1013 f[2] = to->unit[u].objTCoeff.z;
1014 f[3] = to->unit[u].objTCoeff.w;
1015 diff_api.TexGenfv (GL_T, GL_OBJECT_PLANE, (const GLfloat *) f);
1016 from->unit[u].objTCoeff = to->unit[u].objTCoeff;
1017 }
1018 if (from->unit[u].objRCoeff.x != to->unit[u].objRCoeff.x ||
1019 from->unit[u].objRCoeff.y != to->unit[u].objRCoeff.y ||
1020 from->unit[u].objRCoeff.z != to->unit[u].objRCoeff.z ||
1021 from->unit[u].objRCoeff.w != to->unit[u].objRCoeff.w)
1022 {
1023 GLfloat f[4];
1024 f[0] = to->unit[u].objRCoeff.x;
1025 f[1] = to->unit[u].objRCoeff.y;
1026 f[2] = to->unit[u].objRCoeff.z;
1027 f[3] = to->unit[u].objRCoeff.w;
1028 diff_api.TexGenfv (GL_R, GL_OBJECT_PLANE, (const GLfloat *) f);
1029 from->unit[u].objRCoeff = to->unit[u].objRCoeff;
1030 }
1031 if (from->unit[u].objQCoeff.x != to->unit[u].objQCoeff.x ||
1032 from->unit[u].objQCoeff.y != to->unit[u].objQCoeff.y ||
1033 from->unit[u].objQCoeff.z != to->unit[u].objQCoeff.z ||
1034 from->unit[u].objQCoeff.w != to->unit[u].objQCoeff.w)
1035 {
1036 GLfloat f[4];
1037 f[0] = to->unit[u].objQCoeff.x;
1038 f[1] = to->unit[u].objQCoeff.y;
1039 f[2] = to->unit[u].objQCoeff.z;
1040 f[3] = to->unit[u].objQCoeff.w;
1041 diff_api.TexGenfv (GL_Q, GL_OBJECT_PLANE, (const GLfloat *) f);
1042 from->unit[u].objQCoeff = to->unit[u].objQCoeff;
1043 }
1044 CLEARDIRTY(tb->objGen[u], nbitID);
1045 }
1046 if (CHECKDIRTY(tb->eyeGen[u], bitID))
1047 {
1048 if (fromCtx->texture.curTextureUnit != u) {
1049 diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
1050 fromCtx->texture.curTextureUnit = u;
1051 }
1052 if (fromCtx->transform.matrixMode != GL_MODELVIEW) {
1053 diff_api.MatrixMode(GL_MODELVIEW);
1054 fromCtx->transform.matrixMode = GL_MODELVIEW;
1055 }
1056 diff_api.PushMatrix();
1057 diff_api.LoadIdentity();
1058 if (from->unit[u].eyeSCoeff.x != to->unit[u].eyeSCoeff.x ||
1059 from->unit[u].eyeSCoeff.y != to->unit[u].eyeSCoeff.y ||
1060 from->unit[u].eyeSCoeff.z != to->unit[u].eyeSCoeff.z ||
1061 from->unit[u].eyeSCoeff.w != to->unit[u].eyeSCoeff.w)
1062 {
1063 GLfloat f[4];
1064 f[0] = to->unit[u].eyeSCoeff.x;
1065 f[1] = to->unit[u].eyeSCoeff.y;
1066 f[2] = to->unit[u].eyeSCoeff.z;
1067 f[3] = to->unit[u].eyeSCoeff.w;
1068 diff_api.TexGenfv (GL_S, GL_EYE_PLANE, (const GLfloat *) f);
1069 from->unit[u].eyeSCoeff = to->unit[u].eyeSCoeff;
1070 }
1071 if (from->unit[u].eyeTCoeff.x != to->unit[u].eyeTCoeff.x ||
1072 from->unit[u].eyeTCoeff.y != to->unit[u].eyeTCoeff.y ||
1073 from->unit[u].eyeTCoeff.z != to->unit[u].eyeTCoeff.z ||
1074 from->unit[u].eyeTCoeff.w != to->unit[u].eyeTCoeff.w)
1075 {
1076 GLfloat f[4];
1077 f[0] = to->unit[u].eyeTCoeff.x;
1078 f[1] = to->unit[u].eyeTCoeff.y;
1079 f[2] = to->unit[u].eyeTCoeff.z;
1080 f[3] = to->unit[u].eyeTCoeff.w;
1081 diff_api.TexGenfv (GL_T, GL_EYE_PLANE, (const GLfloat *) f);
1082 from->unit[u].eyeTCoeff = to->unit[u].eyeTCoeff;
1083 }
1084 if (from->unit[u].eyeRCoeff.x != to->unit[u].eyeRCoeff.x ||
1085 from->unit[u].eyeRCoeff.y != to->unit[u].eyeRCoeff.y ||
1086 from->unit[u].eyeRCoeff.z != to->unit[u].eyeRCoeff.z ||
1087 from->unit[u].eyeRCoeff.w != to->unit[u].eyeRCoeff.w)
1088 {
1089 GLfloat f[4];
1090 f[0] = to->unit[u].eyeRCoeff.x;
1091 f[1] = to->unit[u].eyeRCoeff.y;
1092 f[2] = to->unit[u].eyeRCoeff.z;
1093 f[3] = to->unit[u].eyeRCoeff.w;
1094 diff_api.TexGenfv (GL_R, GL_EYE_PLANE, (const GLfloat *) f);
1095 from->unit[u].eyeRCoeff = to->unit[u].eyeRCoeff;
1096 }
1097 if (from->unit[u].eyeQCoeff.x != to->unit[u].eyeQCoeff.x ||
1098 from->unit[u].eyeQCoeff.y != to->unit[u].eyeQCoeff.y ||
1099 from->unit[u].eyeQCoeff.z != to->unit[u].eyeQCoeff.z ||
1100 from->unit[u].eyeQCoeff.w != to->unit[u].eyeQCoeff.w)
1101 {
1102 GLfloat f[4];
1103 f[0] = to->unit[u].eyeQCoeff.x;
1104 f[1] = to->unit[u].eyeQCoeff.y;
1105 f[2] = to->unit[u].eyeQCoeff.z;
1106 f[3] = to->unit[u].eyeQCoeff.w;
1107 diff_api.TexGenfv (GL_Q, GL_EYE_PLANE, (const GLfloat *) f);
1108 from->unit[u].eyeQCoeff = to->unit[u].eyeQCoeff;
1109 }
1110 diff_api.PopMatrix();
1111 CLEARDIRTY(tb->eyeGen[u], nbitID);
1112 }
1113 if (CHECKDIRTY(tb->genMode[u], bitID))
1114 {
1115 if (fromCtx->texture.curTextureUnit != u) {
1116 diff_api.ActiveTextureARB( u + GL_TEXTURE0_ARB );
1117 fromCtx->texture.curTextureUnit = u;
1118 }
1119 if (from->unit[u].gen.s != to->unit[u].gen.s ||
1120 from->unit[u].gen.t != to->unit[u].gen.t ||
1121 from->unit[u].gen.r != to->unit[u].gen.r ||
1122 from->unit[u].gen.q != to->unit[u].gen.q)
1123 {
1124 diff_api.TexGeni (GL_S, GL_TEXTURE_GEN_MODE, to->unit[u].gen.s);
1125 diff_api.TexGeni (GL_T, GL_TEXTURE_GEN_MODE, to->unit[u].gen.t);
1126 diff_api.TexGeni (GL_R, GL_TEXTURE_GEN_MODE, to->unit[u].gen.r);
1127 diff_api.TexGeni (GL_Q, GL_TEXTURE_GEN_MODE, to->unit[u].gen.q);
1128 from->unit[u].gen = to->unit[u].gen;
1129 }
1130 CLEARDIRTY(tb->genMode[u], nbitID);
1131 }
1132
1133 /* Texture enviroment */
1134 if (CHECKDIRTY(tb->envBit[u], bitID))
1135 {
1136 if (from->unit[u].envMode != to->unit[u].envMode)
1137 {
1138 diff_api.TexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, to->unit[u].envMode);
1139 from->unit[u].envMode = to->unit[u].envMode;
1140 }
1141 if (from->unit[u].envColor.r != to->unit[u].envColor.r ||
1142 from->unit[u].envColor.g != to->unit[u].envColor.g ||
1143 from->unit[u].envColor.b != to->unit[u].envColor.b ||
1144 from->unit[u].envColor.a != to->unit[u].envColor.a)
1145 {
1146 GLfloat f[4];
1147 f[0] = to->unit[u].envColor.r;
1148 f[1] = to->unit[u].envColor.g;
1149 f[2] = to->unit[u].envColor.b;
1150 f[3] = to->unit[u].envColor.a;
1151 diff_api.TexEnvfv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const GLfloat *) f);
1152 from->unit[u].envColor = to->unit[u].envColor;
1153 }
1154#ifdef CR_ARB_texture_env_combine
1155 if (from->unit[u].combineModeRGB != to->unit[u].combineModeRGB)
1156 {
1157 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, to->unit[u].combineModeRGB);
1158 from->unit[u].combineModeRGB = to->unit[u].combineModeRGB;
1159 }
1160 if (from->unit[u].combineModeA != to->unit[u].combineModeA)
1161 {
1162 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, to->unit[u].combineModeA);
1163 from->unit[u].combineModeA = to->unit[u].combineModeA;
1164 }
1165 if (from->unit[u].combineSourceRGB[0] != to->unit[u].combineSourceRGB[0])
1166 {
1167 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, to->unit[u].combineSourceRGB[0]);
1168 from->unit[u].combineSourceRGB[0] = to->unit[u].combineSourceRGB[0];
1169 }
1170 if (from->unit[u].combineSourceRGB[1] != to->unit[u].combineSourceRGB[1])
1171 {
1172 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, to->unit[u].combineSourceRGB[1]);
1173 from->unit[u].combineSourceRGB[1] = to->unit[u].combineSourceRGB[1];
1174 }
1175 if (from->unit[u].combineSourceRGB[2] != to->unit[u].combineSourceRGB[2])
1176 {
1177 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, to->unit[u].combineSourceRGB[2]);
1178 from->unit[u].combineSourceRGB[2] = to->unit[u].combineSourceRGB[2];
1179 }
1180 if (from->unit[u].combineSourceA[0] != to->unit[u].combineSourceA[0])
1181 {
1182 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, to->unit[u].combineSourceA[0]);
1183 from->unit[u].combineSourceA[0] = to->unit[u].combineSourceA[0];
1184 }
1185 if (from->unit[u].combineSourceA[1] != to->unit[u].combineSourceA[1])
1186 {
1187 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, to->unit[u].combineSourceA[1]);
1188 from->unit[u].combineSourceA[1] = to->unit[u].combineSourceA[1];
1189 }
1190 if (from->unit[u].combineSourceA[2] != to->unit[u].combineSourceA[2])
1191 {
1192 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, to->unit[u].combineSourceA[2]);
1193 from->unit[u].combineSourceA[2] = to->unit[u].combineSourceA[2];
1194 }
1195 if (from->unit[u].combineOperandRGB[0] != to->unit[u].combineOperandRGB[0])
1196 {
1197 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, to->unit[u].combineOperandRGB[0]);
1198 from->unit[u].combineOperandRGB[0] = to->unit[u].combineOperandRGB[0];
1199 }
1200 if (from->unit[u].combineOperandRGB[1] != to->unit[u].combineOperandRGB[1])
1201 {
1202 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, to->unit[u].combineOperandRGB[1]);
1203 from->unit[u].combineOperandRGB[1] = to->unit[u].combineOperandRGB[1];
1204 }
1205 if (from->unit[u].combineOperandRGB[2] != to->unit[u].combineOperandRGB[2])
1206 {
1207 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, to->unit[u].combineOperandRGB[2]);
1208 from->unit[u].combineOperandRGB[2] = to->unit[u].combineOperandRGB[2];
1209 }
1210 if (from->unit[u].combineOperandA[0] != to->unit[u].combineOperandA[0])
1211 {
1212 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, to->unit[u].combineOperandA[0]);
1213 from->unit[u].combineOperandA[0] = to->unit[u].combineOperandA[0];
1214 }
1215 if (from->unit[u].combineOperandA[1] != to->unit[u].combineOperandA[1])
1216 {
1217 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, to->unit[u].combineOperandA[1]);
1218 from->unit[u].combineOperandA[1] = to->unit[u].combineOperandA[1];
1219 }
1220 if (from->unit[u].combineOperandA[2] != to->unit[u].combineOperandA[2])
1221 {
1222 diff_api.TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, to->unit[u].combineOperandA[2]);
1223 from->unit[u].combineOperandA[2] = to->unit[u].combineOperandA[2];
1224 }
1225 if (from->unit[u].combineScaleRGB != to->unit[u].combineScaleRGB)
1226 {
1227 diff_api.TexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, to->unit[u].combineScaleRGB);
1228 from->unit[u].combineScaleRGB = to->unit[u].combineScaleRGB;
1229 }
1230 if (from->unit[u].combineScaleA != to->unit[u].combineScaleA)
1231 {
1232 diff_api.TexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, to->unit[u].combineScaleA);
1233 from->unit[u].combineScaleA = to->unit[u].combineScaleA;
1234 }
1235#endif
1236#if CR_EXT_texture_lod_bias
1237 if (from->unit[u].lodBias != to->unit[u].lodBias)
1238 {
1239 diff_api.TexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, to->unit[u].lodBias);
1240 from->unit[u].lodBias = to->unit[u].lodBias;
1241 }
1242#endif
1243 CLEARDIRTY(tb->envBit[u], nbitID);
1244 }
1245
1246 /* loop over texture targets */
1247 for (t = 0; t < 5; t++)
1248 {
1249 tobj = NULL;
1250
1251 switch (t) {
1252 case 0:
1253 if (to->unit[u].enabled1D || haveFragProg) {
1254 tobj = to->unit[u].currentTexture1D;
1255 fromBinding = &(from->unit[u].currentTexture1D);
1256 }
1257 break;
1258 case 1:
1259 if (to->unit[u].enabled2D || haveFragProg) {
1260 tobj = to->unit[u].currentTexture2D;
1261 fromBinding = &(from->unit[u].currentTexture2D);
1262 }
1263 break;
1264#ifdef CR_OPENGL_VERSION_1_2
1265 case 2:
1266 if (to->unit[u].enabled3D || haveFragProg) {
1267 tobj = to->unit[u].currentTexture3D;
1268 fromBinding = &(from->unit[u].currentTexture3D);
1269 }
1270 break;
1271#endif
1272#ifdef CR_ARB_texture_cube_map
1273 case 3:
1274 if (fromCtx->extensions.ARB_texture_cube_map &&
1275 (to->unit[u].enabledCubeMap || haveFragProg)) {
1276 tobj = to->unit[u].currentTextureCubeMap;
1277 fromBinding = &(from->unit[u].currentTextureCubeMap);
1278 }
1279 break;
1280#endif
1281#ifdef CR_NV_texture_rectangle
1282 case 4:
1283 if (fromCtx->extensions.NV_texture_rectangle &&
1284 (to->unit[u].enabledRect || haveFragProg)) {
1285 tobj = to->unit[u].currentTextureRect;
1286 fromBinding = &(from->unit[u].currentTextureRect);
1287 }
1288 break;
1289#endif
1290 default:
1291 /* maybe don't support cube maps or rects */
1292 continue;
1293 }
1294
1295 if (!tobj) {
1296 continue; /* with next target */
1297 }
1298
1299 /* Activate texture unit u if needed */
1300 if (fromCtx->texture.curTextureUnit != u) {
1301 diff_api.ActiveTextureARB( GL_TEXTURE0_ARB + u);
1302 fromCtx->texture.curTextureUnit = u;
1303 }
1304
1305 /* bind this texture if needed */
1306 if (CHECKDIRTY(tb->current[u], bitID))
1307 {
1308 if (*fromBinding != tobj)
1309 {
1310 diff_api.BindTexture(tobj->target, crStateGetTextureObjHWID(tobj));
1311 *fromBinding = tobj;
1312 }
1313 }
1314
1315 /* now, if the texture object is dirty */
1316 if (CHECKDIRTY(tobj->dirty, bitID))
1317 {
1318 crStateTextureObjectDiff(fromCtx, bitID, nbitID, tobj, GL_FALSE);
1319 }
1320 CLEARDIRTY(tobj->dirty, nbitID);
1321
1322 } /* loop over targets */
1323
1324 CLEARDIRTY(tb->current[u], nbitID);
1325
1326 } /* loop over units */
1327
1328 /* After possible fiddling with the active unit, put it back now */
1329 if (fromCtx->texture.curTextureUnit != toCtx->texture.curTextureUnit) {
1330 diff_api.ActiveTextureARB( toCtx->texture.curTextureUnit + GL_TEXTURE0_ARB );
1331 fromCtx->texture.curTextureUnit = toCtx->texture.curTextureUnit;
1332 }
1333 if (fromCtx->transform.matrixMode != toCtx->transform.matrixMode) {
1334 diff_api.MatrixMode(toCtx->transform.matrixMode);
1335 fromCtx->transform.matrixMode = toCtx->transform.matrixMode;
1336 }
1337
1338 CLEARDIRTY(tb->dirty, nbitID);
1339}
1340
1341
1342
1343struct callback_info
1344{
1345 CRbitvalue *bitID, *nbitID;
1346 CRContext *g;
1347 GLboolean bForceUpdate;
1348};
1349
1350
1351/* Called by crHashtableWalk() below */
1352static void
1353DiffTextureObjectCallback( unsigned long key, void *texObj , void *cbData)
1354{
1355 struct callback_info *info = (struct callback_info *) cbData;
1356 CRTextureObj *tobj = (CRTextureObj *) texObj;
1357 /*
1358 printf(" Checking %d 0x%x bitid=0x%x\n",tobj->name, tobj->dirty[0], info->bitID[0]);
1359 */
1360 if (info->bForceUpdate || CHECKDIRTY(tobj->dirty, info->bitID)) {
1361 /*
1362 printf(" Found Dirty! %d\n", tobj->name);
1363 */
1364 crStateTextureObjectDiff(info->g, info->bitID, info->nbitID, tobj, info->bForceUpdate);
1365 CLEARDIRTY(tobj->dirty, info->nbitID);
1366 }
1367}
1368
1369
1370/*
1371 * This isn't used right now, but will be used in the future to fix some
1372 * potential display list problems. Specifically, if glBindTexture is
1373 * in a display list, we have to be sure that all outstanding texture object
1374 * updates are resolved before the list is called. If we don't, we may
1375 * wind up binding texture objects that are stale.
1376 */
1377void
1378crStateDiffAllTextureObjects( CRContext *g, CRbitvalue *bitID, GLboolean bForceUpdate )
1379{
1380 CRbitvalue nbitID[CR_MAX_BITARRAY];
1381 struct callback_info info;
1382 int j;
1383 int origUnit, orig1D, orig2D, orig3D, origCube, origRect;
1384
1385 for (j = 0; j < CR_MAX_BITARRAY; j++)
1386 nbitID[j] = ~bitID[j];
1387
1388 info.bitID = bitID;
1389 info.nbitID = nbitID;
1390 info.g = g;
1391 info.bForceUpdate = bForceUpdate;
1392
1393 /* save current texture bindings */
1394 origUnit = g->texture.curTextureUnit;
1395 orig1D = crStateGetTextureObjHWID(g->texture.unit[0].currentTexture1D);
1396 orig2D = crStateGetTextureObjHWID(g->texture.unit[0].currentTexture2D);
1397 orig3D = crStateGetTextureObjHWID(g->texture.unit[0].currentTexture3D);
1398#ifdef CR_ARB_texture_cube_map
1399 origCube = crStateGetTextureObjHWID(g->texture.unit[0].currentTextureCubeMap);
1400#endif
1401#ifdef CR_NV_texture_rectangle
1402 origRect = crStateGetTextureObjHWID(g->texture.unit[0].currentTextureRect);
1403#endif
1404
1405 /* use texture unit 0 for updates */
1406 diff_api.ActiveTextureARB(GL_TEXTURE0_ARB);
1407
1408 /* diff all the textures */
1409 crHashtableWalk(g->shared->textureTable, DiffTextureObjectCallback, (void *) &info);
1410
1411 /* default ones */
1412 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.base1D, GL_TRUE);
1413 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.base2D, GL_TRUE);
1414 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.base3D, GL_TRUE);
1415 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxy1D, GL_TRUE);
1416 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxy2D, GL_TRUE);
1417 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxy3D, GL_TRUE);
1418#ifdef CR_ARB_texture_cube_map
1419 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.baseCubeMap, GL_TRUE);
1420 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxyCubeMap, GL_TRUE);
1421#endif
1422#ifdef CR_NV_texture_rectangle
1423 if (g->extensions.NV_texture_rectangle)
1424 {
1425 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.baseRect, GL_TRUE);
1426 crStateTextureObjectDiff(g, bitID, nbitID, &g->texture.proxyRect, GL_TRUE);
1427 }
1428#endif
1429
1430 /* restore bindings */
1431 diff_api.ActiveTextureARB(GL_TEXTURE0_ARB + origUnit);
1432 diff_api.BindTexture(GL_TEXTURE_1D, orig1D);
1433 diff_api.BindTexture(GL_TEXTURE_2D, orig2D);
1434 diff_api.BindTexture(GL_TEXTURE_3D, orig3D);
1435#ifdef CR_ARB_texture_cube_map
1436 diff_api.BindTexture(GL_TEXTURE_CUBE_MAP_ARB, origCube);
1437#endif
1438#ifdef CR_NV_texture_rectangle
1439 diff_api.BindTexture(GL_TEXTURE_RECTANGLE_NV, origRect);
1440#endif
1441}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette