VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_snapshot.c@ 44059

Last change on this file since 44059 was 44048, checked in by vboxsync, 12 years ago

crOpenGL: fix saved state crash

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 93.9 KB
Line 
1/* $Id: state_snapshot.c 44048 2012-12-06 10:21:28Z vboxsync $ */
2
3/** @file
4 * VBox Context state saving/loading used by VM snapshot
5 */
6
7/*
8 * Copyright (C) 2008 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "state.h"
20#include "state_internals.h"
21#include "state/cr_statetypes.h"
22#include "state/cr_texture.h"
23#include "cr_mem.h"
24#include "cr_string.h"
25#include "cr_pixeldata.h"
26#include <stdio.h>
27
28#include <iprt/assert.h>
29#include <iprt/types.h>
30#include <iprt/err.h>
31#include <VBox/err.h>
32
33/* @todo
34 * We have two ways of saving/loading states.
35 *
36 * First which is being used atm, just pure saving/loading of structures.
37 * The drawback is we have to deal with all the pointers around those structures,
38 * we'd have to update this code if we'd change state tracking.
39 * On the bright side it's fast, though it's not really needed as it's not that often operation.
40 * It could also worth to split those functions into appropriate parts,
41 * similar to the way context creation is being done.
42 *
43 * Second way would be to implement full dispatch api table and substitute diff_api during saving/loading.
44 * Then if we implement that api in a similar way to packer/unpacker with a change to store/load
45 * via provided pSSM handle instead of pack buffer,
46 * saving state could be done by simple diffing against empty "dummy" context.
47 * Restoring state in such case would look like unpacking commands from pSSM instead of network buffer.
48 * This would be slower (who cares) but most likely will not require any code changes to support in future.
49 * We will reduce amount of saved data as we'd save only changed state parts, but I doubt it'd be that much.
50 * It could be done for the first way as well, but requires tons of bit checks.
51 */
52
53static int32_t crStateAllocAndSSMR3GetMem(PSSMHANDLE pSSM, void **pBuffer, size_t cbBuffer)
54{
55 CRASSERT(pSSM && pBuffer && cbBuffer>0);
56
57 *pBuffer = crAlloc(cbBuffer);
58 if (!*pBuffer)
59 return VERR_NO_MEMORY;
60
61 return SSMR3GetMem(pSSM, *pBuffer, cbBuffer);
62}
63
64#define SHCROGL_GET_STRUCT_PART(_pPtr, _type, _from, _to) do { \
65 rc = SSMR3GetMem(pSSM, &(_pPtr)->_from, RT_OFFSETOF(_type, _to) - RT_OFFSETOF(_type, _from)); \
66 AssertRCReturn(rc, rc); \
67 } while (0)
68
69#define SHCROGL_GET_STRUCT_TAIL(_pPtr, _type, _from) do { \
70 rc = SSMR3GetMem(pSSM, &(_pPtr)->_from, sizeof (_type) - RT_OFFSETOF(_type, _from)); \
71 AssertRCReturn(rc, rc); \
72 } while (0)
73
74#define SHCROGL_GET_STRUCT_HEAD(_pPtr, _type, _to) do { \
75 rc = SSMR3GetMem(pSSM, (_pPtr), RT_OFFSETOF(_type, _to)); \
76 AssertRCReturn(rc, rc); \
77 } while (0)
78
79#define SHCROGL_CUT_FIELD_ALIGNMENT_SIZE(_type, _prevField, _field) (RT_OFFSETOF(_type, _field) - RT_OFFSETOF(_type, _prevField) - RT_SIZEOFMEMB(_type, _prevField))
80#define SHCROGL_CUT_FIELD_ALIGNMENT(_type, _prevField, _field) do { \
81 const int32_t cbAlignment = SHCROGL_CUT_FIELD_ALIGNMENT_SIZE(_type, _prevField, _field) ; \
82 /*AssertCompile(SHCROGL_CUT_FIELD_ALIGNMENT_SIZE(_type, _prevField, _field) >= 0 && SHCROGL_CUT_FIELD_ALIGNMENT_SIZE(_type, _prevField, _field) < sizeof (void*));*/ \
83 if (cbAlignment) { \
84 rc = SSMR3Skip(pSSM, cbAlignment); \
85 } \
86 } while (0)
87
88#define SHCROGL_CUT_TAIL_ALIGNMENT_SIZE(_type, _lastField) (sizeof (_type) - RT_OFFSETOF(_type, _lastField) - RT_SIZEOFMEMB(_type, _lastField))
89#define SHCROGL_CUT_TAIL_ALIGNMENT(_type, _lastField) do { \
90 const int32_t cbAlignment = SHCROGL_CUT_TAIL_ALIGNMENT_SIZE(_type, _lastField); \
91 /*AssertCompile(SHCROGL_CUT_TAIL_ALIGNMENT_SIZE(_type, _lastField) >= 0 && SHCROGL_CUT_TAIL_ALIGNMENT_SIZE(_type, _lastField) < sizeof (void*));*/ \
92 if (cbAlignment) { \
93 rc = SSMR3Skip(pSSM, cbAlignment); \
94 } \
95 } while (0)
96
97static int32_t crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(CRTextureObj *pTexture, PSSMHANDLE pSSM)
98{
99 int32_t rc;
100 uint32_t cbObj = RT_OFFSETOF(CRTextureObj, ctxUsage);
101 cbObj = ((cbObj + sizeof (void*) - 1) & ~(sizeof (void*) - 1));
102 rc = SSMR3GetMem(pSSM, pTexture, cbObj);
103 AssertRCReturn(rc, rc);
104 /* just make all bits are used so that we fall back to the pre-ctxUsage behavior,
105 * i.e. all shared resources will be destructed on last shared context termination */
106 FILLDIRTY(pTexture->ctxUsage);
107 return rc;
108}
109
110static int32_t crStateLoadTextureUnit_v_BEFORE_CTXUSAGE_BITS(CRTextureUnit *t, PSSMHANDLE pSSM)
111{
112 int32_t rc;
113 SHCROGL_GET_STRUCT_HEAD(t, CRTextureUnit, Saved1D);
114 rc = crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(&t->Saved1D, pSSM);
115 AssertRCReturn(rc, rc);
116 SHCROGL_CUT_FIELD_ALIGNMENT(CRTextureUnit, Saved1D, Saved2D);
117 rc = crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(&t->Saved2D, pSSM);
118 AssertRCReturn(rc, rc);
119 SHCROGL_CUT_FIELD_ALIGNMENT(CRTextureUnit, Saved2D, Saved3D);
120 rc = crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(&t->Saved3D, pSSM);
121 AssertRCReturn(rc, rc);
122#ifdef CR_ARB_texture_cube_map
123 SHCROGL_CUT_FIELD_ALIGNMENT(CRTextureUnit, Saved3D, SavedCubeMap);
124 rc = crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(&t->SavedCubeMap, pSSM);
125 AssertRCReturn(rc, rc);
126# define SHCROGL_INTERNAL_LAST_FIELD SavedCubeMap
127#else
128# define SHCROGL_INTERNAL_LAST_FIELD Saved3D
129#endif
130#ifdef CR_NV_texture_rectangle
131 SHCROGL_CUT_FIELD_ALIGNMENT(CRTextureUnit, SHCROGL_INTERNAL_LAST_FIELD, SavedRect);
132 rc = crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(&t->SavedRect, pSSM);
133 AssertRCReturn(rc, rc);
134# undef SHCROGL_INTERNAL_LAST_FIELD
135# define SHCROGL_INTERNAL_LAST_FIELD SavedRect
136#endif
137 SHCROGL_CUT_TAIL_ALIGNMENT(CRTextureUnit, SHCROGL_INTERNAL_LAST_FIELD);
138#undef SHCROGL_INTERNAL_LAST_FIELD
139 return rc;
140}
141
142static int32_t crStateLoadTextureState_v_BEFORE_CTXUSAGE_BITS(CRTextureState *t, PSSMHANDLE pSSM)
143{
144 GLint i;
145 int32_t rc = crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(&t->base1D, pSSM);
146 AssertRCReturn(rc, rc);
147 SHCROGL_CUT_FIELD_ALIGNMENT(CRTextureState, base1D, base2D);
148 rc = crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(&t->base2D, pSSM);
149 AssertRCReturn(rc, rc);
150 rc = crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(&t->base3D, pSSM);
151 SHCROGL_CUT_FIELD_ALIGNMENT(CRTextureState, base2D, base3D);
152 AssertRCReturn(rc, rc);
153#ifdef CR_ARB_texture_cube_map
154 SHCROGL_CUT_FIELD_ALIGNMENT(CRTextureState, base3D, baseCubeMap);
155 rc = crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(&t->baseCubeMap, pSSM);
156 AssertRCReturn(rc, rc);
157# define SHCROGL_INTERNAL_LAST_FIELD baseCubeMap
158#else
159# define SHCROGL_INTERNAL_LAST_FIELD base3D
160#endif
161#ifdef CR_NV_texture_rectangle
162 SHCROGL_CUT_FIELD_ALIGNMENT(CRTextureState, SHCROGL_INTERNAL_LAST_FIELD, baseRect);
163 rc = crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(&t->baseRect, pSSM);
164 AssertRCReturn(rc, rc);
165# undef SHCROGL_INTERNAL_LAST_FIELD
166# define SHCROGL_INTERNAL_LAST_FIELD baseRect
167#endif
168 SHCROGL_CUT_FIELD_ALIGNMENT(CRTextureState, SHCROGL_INTERNAL_LAST_FIELD, proxy1D);
169 rc = crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(&t->proxy1D, pSSM);
170 AssertRCReturn(rc, rc);
171#undef SHCROGL_INTERNAL_LAST_FIELD
172 SHCROGL_CUT_FIELD_ALIGNMENT(CRTextureState, proxy1D, proxy2D);
173 rc = crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(&t->proxy2D, pSSM);
174 AssertRCReturn(rc, rc);
175 SHCROGL_CUT_FIELD_ALIGNMENT(CRTextureState, proxy2D, proxy3D);
176 rc = crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(&t->proxy3D, pSSM);
177 AssertRCReturn(rc, rc);
178#ifdef CR_ARB_texture_cube_map
179 SHCROGL_CUT_FIELD_ALIGNMENT(CRTextureState, proxy3D, proxyCubeMap);
180 rc = crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(&t->proxyCubeMap, pSSM);
181 AssertRCReturn(rc, rc);
182# define SHCROGL_INTERNAL_LAST_FIELD proxyCubeMap
183#else
184# define SHCROGL_INTERNAL_LAST_FIELD proxy3D
185#endif
186#ifdef CR_NV_texture_rectangle
187 SHCROGL_CUT_FIELD_ALIGNMENT(CRTextureState, SHCROGL_INTERNAL_LAST_FIELD, proxyRect);
188 rc = crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(&t->proxyRect, pSSM);
189 AssertRCReturn(rc, rc);
190# undef SHCROGL_INTERNAL_LAST_FIELD
191# define SHCROGL_INTERNAL_LAST_FIELD proxyRect
192#endif
193 SHCROGL_CUT_FIELD_ALIGNMENT(CRTextureState, SHCROGL_INTERNAL_LAST_FIELD, curTextureUnit);
194# undef SHCROGL_INTERNAL_LAST_FIELD
195 SHCROGL_GET_STRUCT_PART(t, CRTextureState, curTextureUnit, unit);
196
197 for (i = 0; i < CR_MAX_TEXTURE_UNITS; ++i)
198 {
199 rc = crStateLoadTextureUnit_v_BEFORE_CTXUSAGE_BITS(&t->unit[i], pSSM);
200 AssertRCReturn(rc, rc);
201 }
202
203 SHCROGL_CUT_TAIL_ALIGNMENT(CRTextureState, unit);
204
205 return rc;
206}
207
208static int32_t crStateLoadTextureStack_v_BEFORE_CTXUSAGE_BITS(CRTextureStack *t, PSSMHANDLE pSSM)
209{
210 int32_t i, rc;
211 SHCROGL_GET_STRUCT_HEAD(t, CRTextureStack, unit);
212 for (i = 0; i < CR_MAX_TEXTURE_UNITS; ++i)
213 {
214 rc = crStateLoadTextureUnit_v_BEFORE_CTXUSAGE_BITS(&t->unit[i], pSSM);
215 AssertRCReturn(rc, rc);
216 }
217 SHCROGL_CUT_TAIL_ALIGNMENT(CRTextureStack, unit);
218 return rc;
219}
220
221static int32_t crStateLoadAttribState_v_BEFORE_CTXUSAGE_BITS(CRAttribState *t, PSSMHANDLE pSSM)
222{
223 int32_t i, rc;
224 SHCROGL_GET_STRUCT_HEAD(t, CRAttribState, textureStack);
225 for (i = 0; i < CR_MAX_ATTRIB_STACK_DEPTH; ++i)
226 {
227 rc = crStateLoadTextureStack_v_BEFORE_CTXUSAGE_BITS(&t->textureStack[i], pSSM);
228 AssertRCReturn(rc, rc);
229 }
230 SHCROGL_GET_STRUCT_TAIL(t, CRAttribState, transformStackDepth);
231 return rc;
232}
233
234
235static int32_t crStateLoadTextureObj(CRTextureObj *pTexture, PSSMHANDLE pSSM, uint32_t u32Version)
236{
237 int32_t rc;
238 if (u32Version == SHCROGL_SSM_VERSION_BEFORE_CTXUSAGE_BITS)
239 return crStateLoadTextureObj_v_BEFORE_CTXUSAGE_BITS(pTexture, pSSM);
240 rc = SSMR3GetMem(pSSM, pTexture, sizeof (*pTexture));
241 AssertRCReturn(rc, rc);
242 return rc;
243}
244
245static int32_t crStateLoadBufferObject(CRBufferObject *pBufferObj, PSSMHANDLE pSSM, uint32_t u32Version)
246{
247 int32_t rc;
248 if (u32Version == SHCROGL_SSM_VERSION_BEFORE_CTXUSAGE_BITS)
249 {
250 uint32_t cbObj = RT_OFFSETOF(CRBufferObject, ctxUsage);
251 cbObj = ((cbObj + sizeof (void*) - 1) & ~(sizeof (void*) - 1));
252 rc = SSMR3GetMem(pSSM, pBufferObj, cbObj);
253 AssertRCReturn(rc, rc);
254 /* just make all bits are used so that we fall back to the pre-ctxUsage behavior,
255 * i.e. all shared resources will be destructed on last shared context termination */
256 FILLDIRTY(pBufferObj->ctxUsage);
257 }
258 else
259 {
260 rc = SSMR3GetMem(pSSM, pBufferObj, sizeof(*pBufferObj));
261 AssertRCReturn(rc, rc);
262 }
263 return rc;
264}
265
266static int32_t crStateLoadFramebufferObject(CRFramebufferObject *pFBO, PSSMHANDLE pSSM, uint32_t u32Version)
267{
268 int32_t rc;
269 if (u32Version == SHCROGL_SSM_VERSION_BEFORE_CTXUSAGE_BITS)
270 {
271 uint32_t cbObj = RT_OFFSETOF(CRFramebufferObject, ctxUsage);
272 cbObj = ((cbObj + sizeof (void*) - 1) & ~(sizeof (void*) - 1));
273 rc = SSMR3GetMem(pSSM, pFBO, cbObj);
274 AssertRCReturn(rc, rc);
275 /* just make all bits are used so that we fall back to the pre-ctxUsage behavior,
276 * i.e. all shared resources will be destructed on last shared context termination */
277 FILLDIRTY(pFBO->ctxUsage);
278 }
279 else
280 {
281 rc = SSMR3GetMem(pSSM, pFBO, sizeof(*pFBO));
282 AssertRCReturn(rc, rc);
283 }
284 return rc;
285}
286
287static int32_t crStateLoadRenderbufferObject(CRRenderbufferObject *pRBO, PSSMHANDLE pSSM, uint32_t u32Version)
288{
289 int32_t rc;
290 if (u32Version == SHCROGL_SSM_VERSION_BEFORE_CTXUSAGE_BITS)
291 {
292 uint32_t cbObj = RT_OFFSETOF(CRRenderbufferObject, ctxUsage);
293 cbObj = ((cbObj + sizeof (void*) - 1) & ~(sizeof (void*) - 1));
294 rc = SSMR3GetMem(pSSM, pRBO, cbObj);
295 AssertRCReturn(rc, rc);
296 /* just make all bits are used so that we fall back to the pre-ctxUsage behavior,
297 * i.e. all shared resources will be destructed on last shared context termination */
298 FILLDIRTY(pRBO->ctxUsage);
299 }
300 else
301 {
302 rc = SSMR3GetMem(pSSM, pRBO, sizeof(*pRBO));
303 AssertRCReturn(rc, rc);
304 }
305 return rc;
306}
307
308static int32_t crStateSaveTextureObjData(CRTextureObj *pTexture, PSSMHANDLE pSSM)
309{
310 int32_t rc, face, i;
311 GLint bound = 0;
312
313 CRASSERT(pTexture && pSSM);
314
315 crDebug("crStateSaveTextureObjData %u. START", pTexture->id);
316
317 for (face = 0; face < 6; face++) {
318 CRASSERT(pTexture->level[face]);
319
320 for (i = 0; i < CR_MAX_MIPMAP_LEVELS; i++) {
321 CRTextureLevel *ptl = &(pTexture->level[face][i]);
322 rc = SSMR3PutMem(pSSM, ptl, sizeof(*ptl));
323 AssertRCReturn(rc, rc);
324 if (ptl->img)
325 {
326 CRASSERT(ptl->bytes);
327 rc = SSMR3PutMem(pSSM, ptl->img, ptl->bytes);
328 AssertRCReturn(rc, rc);
329 }
330#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
331 /* Note, this is not a bug.
332 * Even with CR_STATE_NO_TEXTURE_IMAGE_STORE defined, it's possible that ptl->img!=NULL.
333 * For ex. we're saving snapshot right after it was loaded
334 * and some context hasn't been used by the guest application yet
335 * (pContext->shared->bTexResyncNeeded==GL_TRUE).
336 */
337 else if (ptl->bytes)
338 {
339 char *pImg;
340 GLenum target;
341
342 if (!bound)
343 {
344 GLenum getEnum;
345 diff_api.BindTexture(pTexture->target, pTexture->hwid);
346 bound = 1;
347
348 /* osx nvidia drivers seem to have a bug that 1x1 TEXTURE_2D texture becmes inaccessible for some reason
349 * saw that for 1x1 dummy textures generated by wine
350 * to avoid crashes we skip texture data save if that is the case */
351 switch (pTexture->target)
352 {
353 case GL_TEXTURE_1D:
354 getEnum = GL_TEXTURE_BINDING_1D;
355 break;
356 case GL_TEXTURE_2D:
357 getEnum = GL_TEXTURE_BINDING_2D;
358 break;
359 case GL_TEXTURE_3D:
360 getEnum = GL_TEXTURE_BINDING_3D;
361 break;
362 case GL_TEXTURE_RECTANGLE_ARB:
363 getEnum = GL_TEXTURE_BINDING_RECTANGLE_ARB;
364 break;
365 case GL_TEXTURE_CUBE_MAP_ARB:
366 getEnum = GL_TEXTURE_BINDING_CUBE_MAP_ARB;
367 break;
368 default:
369 crWarning("unknown texture target: 0x%x", pTexture->target);
370 getEnum = 0;
371 break;
372 }
373
374 if (getEnum)
375 {
376 GLint curTex;
377 diff_api.GetIntegerv(getEnum, &curTex);
378 if (curTex != pTexture->hwid)
379 {
380 crWarning("texture not bound properly: expected %d, but was %d. Texture state data: target(0x%x), id(%d), w(%d), h(%d)",
381 pTexture->hwid, curTex,
382 pTexture->target,
383 pTexture->id,
384 ptl->width,
385 ptl->height);
386 bound = -1;
387 }
388 }
389
390 }
391
392 if (pTexture->target!=GL_TEXTURE_CUBE_MAP_ARB)
393 {
394 target = pTexture->target;
395 }
396 else
397 {
398 target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
399 }
400
401#ifdef DEBUG
402 pImg = crAlloc(ptl->bytes+4);
403#else
404 pImg = crAlloc(ptl->bytes);
405#endif
406 if (!pImg) return VERR_NO_MEMORY;
407
408#ifdef DEBUG
409 *(int*)((char*)pImg+ptl->bytes) = 0xDEADDEAD;
410#endif
411 if (bound > 0)
412 {
413#ifdef DEBUG
414 {
415 GLint w,h=0;
416 crDebug("get image: compressed %i, face %i, level %i, width %i, height %i, bytes %i",
417 ptl->compressed, face, i, ptl->width, ptl->height, ptl->bytes);
418 diff_api.GetTexLevelParameteriv(target, i, GL_TEXTURE_WIDTH, &w);
419 diff_api.GetTexLevelParameteriv(target, i, GL_TEXTURE_HEIGHT, &h);
420 if (w!=ptl->width || h!=ptl->height)
421 {
422 crWarning("!!!tex size mismatch %i, %i!!!", w, h);
423 }
424 }
425#endif
426
427 /*@todo: ugly workaround for crashes inside ati driver,
428 * they overwrite their own allocated memory in cases where texlevel >=4
429 and width or height <=2.
430 */
431 if (i<4 || (ptl->width>2 && ptl->height>2))
432 {
433 if (!ptl->compressed)
434 {
435 diff_api.GetTexImage(target, i, ptl->format, ptl->type, pImg);
436 }
437 else
438 {
439 diff_api.GetCompressedTexImageARB(target, i, pImg);
440 }
441 }
442 }
443 else
444 {
445 crMemset(pImg, 0, ptl->bytes);
446 }
447
448#ifdef DEBUG
449 if (*(int*)((char*)pImg+ptl->bytes) != 0xDEADDEAD)
450 {
451 crWarning("Texture is bigger than expected!!!");
452 }
453#endif
454
455 rc = SSMR3PutMem(pSSM, pImg, ptl->bytes);
456 crFree(pImg);
457 AssertRCReturn(rc, rc);
458 }
459#endif
460 }
461 }
462
463 crDebug("crStateSaveTextureObjData %u. END", pTexture->id);
464
465 return VINF_SUCCESS;
466}
467
468static int32_t crStateLoadTextureObjData(CRTextureObj *pTexture, PSSMHANDLE pSSM)
469{
470 int32_t rc, face, i;
471
472 CRASSERT(pTexture && pSSM);
473
474 for (face = 0; face < 6; face++) {
475 CRASSERT(pTexture->level[face]);
476
477 for (i = 0; i < CR_MAX_MIPMAP_LEVELS; i++) {
478 CRTextureLevel *ptl = &(pTexture->level[face][i]);
479 CRASSERT(!ptl->img);
480
481 rc = SSMR3GetMem(pSSM, ptl, sizeof(*ptl));
482 AssertRCReturn(rc, rc);
483 if (ptl->img)
484 {
485 CRASSERT(ptl->bytes);
486
487 ptl->img = crAlloc(ptl->bytes);
488 if (!ptl->img) return VERR_NO_MEMORY;
489
490 rc = SSMR3GetMem(pSSM, ptl->img, ptl->bytes);
491 AssertRCReturn(rc, rc);
492 }
493#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
494 /* Same story as in crStateSaveTextureObjData */
495 else if (ptl->bytes)
496 {
497 ptl->img = crAlloc(ptl->bytes);
498 if (!ptl->img) return VERR_NO_MEMORY;
499
500 rc = SSMR3GetMem(pSSM, ptl->img, ptl->bytes);
501 AssertRCReturn(rc, rc);
502 }
503#endif
504 crStateTextureInitTextureFormat(ptl, ptl->internalFormat);
505 }
506 }
507
508 return VINF_SUCCESS;
509}
510
511static void crStateSaveSharedTextureCB(unsigned long key, void *data1, void *data2)
512{
513 CRTextureObj *pTexture = (CRTextureObj *) data1;
514 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
515 int32_t rc;
516
517 CRASSERT(pTexture && pSSM);
518
519 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
520 CRASSERT(rc == VINF_SUCCESS);
521 rc = SSMR3PutMem(pSSM, pTexture, sizeof(*pTexture));
522 CRASSERT(rc == VINF_SUCCESS);
523 rc = crStateSaveTextureObjData(pTexture, pSSM);
524 CRASSERT(rc == VINF_SUCCESS);
525}
526
527static int32_t crStateSaveMatrixStack(CRMatrixStack *pStack, PSSMHANDLE pSSM)
528{
529 return SSMR3PutMem(pSSM, pStack->stack, sizeof(CRmatrix) * pStack->maxDepth);
530}
531
532static int32_t crStateLoadMatrixStack(CRMatrixStack *pStack, PSSMHANDLE pSSM)
533{
534 int32_t rc;
535
536 CRASSERT(pStack && pSSM);
537
538 rc = SSMR3GetMem(pSSM, pStack->stack, sizeof(CRmatrix) * pStack->maxDepth);
539 /* fixup stack top pointer */
540 pStack->top = &pStack->stack[pStack->depth];
541 return rc;
542}
543
544static int32_t crStateSaveTextureObjPtr(CRTextureObj *pTexture, PSSMHANDLE pSSM)
545{
546 /* Current texture pointer can't be NULL for real texture unit states,
547 * but it could be NULL for unused attribute stack depths.
548 */
549 if (pTexture)
550 return SSMR3PutU32(pSSM, pTexture->id);
551 else
552 return VINF_SUCCESS;
553}
554
555static int32_t crStateLoadTextureObjPtr(CRTextureObj **pTexture, CRContext *pContext, GLenum target, PSSMHANDLE pSSM)
556{
557 uint32_t texName;
558 int32_t rc;
559
560 /* We're loading attrib stack with unused state */
561 if (!*pTexture)
562 return VINF_SUCCESS;
563
564 rc = SSMR3GetU32(pSSM, &texName);
565 AssertRCReturn(rc, rc);
566
567 if (texName)
568 {
569 *pTexture = (CRTextureObj *) crHashtableSearch(pContext->shared->textureTable, texName);
570 }
571 else
572 {
573 switch (target)
574 {
575 case GL_TEXTURE_1D:
576 *pTexture = &(pContext->texture.base1D);
577 break;
578 case GL_TEXTURE_2D:
579 *pTexture = &(pContext->texture.base2D);
580 break;
581#ifdef CR_OPENGL_VERSION_1_2
582 case GL_TEXTURE_3D:
583 *pTexture = &(pContext->texture.base3D);
584 break;
585#endif
586#ifdef CR_ARB_texture_cube_map
587 case GL_TEXTURE_CUBE_MAP_ARB:
588 *pTexture = &(pContext->texture.baseCubeMap);
589 break;
590#endif
591#ifdef CR_NV_texture_rectangle
592 case GL_TEXTURE_RECTANGLE_NV:
593 *pTexture = &(pContext->texture.baseRect);
594 break;
595#endif
596 default:
597 crError("LoadTextureObjPtr: Unknown texture target %d", target);
598 }
599 }
600
601 return rc;
602}
603
604static int32_t crStateSaveTexUnitCurrentTexturePtrs(CRTextureUnit *pTexUnit, PSSMHANDLE pSSM)
605{
606 int32_t rc;
607
608 rc = crStateSaveTextureObjPtr(pTexUnit->currentTexture1D, pSSM);
609 AssertRCReturn(rc, rc);
610 rc = crStateSaveTextureObjPtr(pTexUnit->currentTexture2D, pSSM);
611 AssertRCReturn(rc, rc);
612 rc = crStateSaveTextureObjPtr(pTexUnit->currentTexture3D, pSSM);
613 AssertRCReturn(rc, rc);
614#ifdef CR_ARB_texture_cube_map
615 rc = crStateSaveTextureObjPtr(pTexUnit->currentTextureCubeMap, pSSM);
616 AssertRCReturn(rc, rc);
617#endif
618#ifdef CR_NV_texture_rectangle
619 rc = crStateSaveTextureObjPtr(pTexUnit->currentTextureRect, pSSM);
620 AssertRCReturn(rc, rc);
621#endif
622
623 return rc;
624}
625
626static int32_t crStateLoadTexUnitCurrentTexturePtrs(CRTextureUnit *pTexUnit, CRContext *pContext, PSSMHANDLE pSSM)
627{
628 int32_t rc;
629
630 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTexture1D, pContext, GL_TEXTURE_1D, pSSM);
631 AssertRCReturn(rc, rc);
632 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTexture2D, pContext, GL_TEXTURE_1D, pSSM);
633 AssertRCReturn(rc, rc);
634 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTexture3D, pContext, GL_TEXTURE_2D, pSSM);
635 AssertRCReturn(rc, rc);
636#ifdef CR_ARB_texture_cube_map
637 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTextureCubeMap, pContext, GL_TEXTURE_CUBE_MAP_ARB, pSSM);
638 AssertRCReturn(rc, rc);
639#endif
640#ifdef CR_NV_texture_rectangle
641 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTextureRect, pContext, GL_TEXTURE_RECTANGLE_NV, pSSM);
642 AssertRCReturn(rc, rc);
643#endif
644
645 return rc;
646}
647
648static int32_t crSateSaveEvalCoeffs1D(CREvaluator1D *pEval, PSSMHANDLE pSSM)
649{
650 int32_t rc, i;
651
652 for (i=0; i<GLEVAL_TOT; ++i)
653 {
654 if (pEval[i].coeff)
655 {
656 rc = SSMR3PutMem(pSSM, pEval[i].coeff, pEval[i].order * gleval_sizes[i] * sizeof(GLfloat));
657 AssertRCReturn(rc, rc);
658 }
659 }
660
661 return VINF_SUCCESS;
662}
663
664static int32_t crSateSaveEvalCoeffs2D(CREvaluator2D *pEval, PSSMHANDLE pSSM)
665{
666 int32_t rc, i;
667
668 for (i=0; i<GLEVAL_TOT; ++i)
669 {
670 if (pEval[i].coeff)
671 {
672 rc = SSMR3PutMem(pSSM, pEval[i].coeff, pEval[i].uorder * pEval[i].vorder * gleval_sizes[i] * sizeof(GLfloat));
673 AssertRCReturn(rc, rc);
674 }
675 }
676
677 return VINF_SUCCESS;
678}
679
680static int32_t crSateLoadEvalCoeffs1D(CREvaluator1D *pEval, GLboolean bReallocMem, PSSMHANDLE pSSM)
681{
682 int32_t rc, i;
683 size_t size;
684
685 for (i=0; i<GLEVAL_TOT; ++i)
686 {
687 if (pEval[i].coeff)
688 {
689 size = pEval[i].order * gleval_sizes[i] * sizeof(GLfloat);
690 if (bReallocMem)
691 {
692 pEval[i].coeff = (GLfloat*) crAlloc(size);
693 if (!pEval[i].coeff) return VERR_NO_MEMORY;
694 }
695 rc = SSMR3GetMem(pSSM, pEval[i].coeff, size);
696 AssertRCReturn(rc, rc);
697 }
698 }
699
700 return VINF_SUCCESS;
701}
702
703static int32_t crSateLoadEvalCoeffs2D(CREvaluator2D *pEval, GLboolean bReallocMem, PSSMHANDLE pSSM)
704{
705 int32_t rc, i;
706 size_t size;
707
708 for (i=0; i<GLEVAL_TOT; ++i)
709 {
710 if (pEval[i].coeff)
711 {
712 size = pEval[i].uorder * pEval[i].vorder * gleval_sizes[i] * sizeof(GLfloat);
713 if (bReallocMem)
714 {
715 pEval[i].coeff = (GLfloat*) crAlloc(size);
716 if (!pEval[i].coeff) return VERR_NO_MEMORY;
717 }
718 rc = SSMR3GetMem(pSSM, pEval[i].coeff, size);
719 AssertRCReturn(rc, rc);
720 }
721 }
722
723 return VINF_SUCCESS;
724}
725
726static void crStateCopyEvalPtrs1D(CREvaluator1D *pDst, CREvaluator1D *pSrc)
727{
728 int32_t i;
729
730 for (i=0; i<GLEVAL_TOT; ++i)
731 pDst[i].coeff = pSrc[i].coeff;
732
733 /*
734 pDst[GL_MAP1_VERTEX_3-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_VERTEX_3-GL_MAP1_COLOR_4].coeff;
735 pDst[GL_MAP1_VERTEX_4-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_VERTEX_4-GL_MAP1_COLOR_4].coeff;
736 pDst[GL_MAP1_INDEX-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_INDEX-GL_MAP1_COLOR_4].coeff;
737 pDst[GL_MAP1_COLOR_4-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_COLOR_4-GL_MAP1_COLOR_4].coeff;
738 pDst[GL_MAP1_NORMAL-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_NORMAL-GL_MAP1_COLOR_4].coeff;
739 pDst[GL_MAP1_TEXTURE_COORD_1-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_1-GL_MAP1_COLOR_4].coeff;
740 pDst[GL_MAP1_TEXTURE_COORD_2-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_2-GL_MAP1_COLOR_4].coeff;
741 pDst[GL_MAP1_TEXTURE_COORD_3-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_3-GL_MAP1_COLOR_4].coeff;
742 pDst[GL_MAP1_TEXTURE_COORD_4-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_4-GL_MAP1_COLOR_4].coeff;
743 */
744}
745
746static void crStateCopyEvalPtrs2D(CREvaluator2D *pDst, CREvaluator2D *pSrc)
747{
748 int32_t i;
749
750 for (i=0; i<GLEVAL_TOT; ++i)
751 pDst[i].coeff = pSrc[i].coeff;
752
753 /*
754 pDst[GL_MAP2_VERTEX_3-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_VERTEX_3-GL_MAP2_COLOR_4].coeff;
755 pDst[GL_MAP2_VERTEX_4-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_VERTEX_4-GL_MAP2_COLOR_4].coeff;
756 pDst[GL_MAP2_INDEX-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_INDEX-GL_MAP2_COLOR_4].coeff;
757 pDst[GL_MAP2_COLOR_4-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_COLOR_4-GL_MAP2_COLOR_4].coeff;
758 pDst[GL_MAP2_NORMAL-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_NORMAL-GL_MAP2_COLOR_4].coeff;
759 pDst[GL_MAP2_TEXTURE_COORD_1-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_1-GL_MAP2_COLOR_4].coeff;
760 pDst[GL_MAP2_TEXTURE_COORD_2-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_2-GL_MAP2_COLOR_4].coeff;
761 pDst[GL_MAP2_TEXTURE_COORD_3-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_3-GL_MAP2_COLOR_4].coeff;
762 pDst[GL_MAP2_TEXTURE_COORD_4-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_4-GL_MAP2_COLOR_4].coeff;
763 */
764}
765
766static void crStateSaveBufferObjectCB(unsigned long key, void *data1, void *data2)
767{
768 CRBufferObject *pBufferObj = (CRBufferObject *) data1;
769 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
770 int32_t rc;
771
772 CRASSERT(pBufferObj && pSSM);
773
774 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
775 CRASSERT(rc == VINF_SUCCESS);
776 rc = SSMR3PutMem(pSSM, pBufferObj, sizeof(*pBufferObj));
777 CRASSERT(rc == VINF_SUCCESS);
778
779 if (pBufferObj->data)
780 {
781 /*We could get here even though retainBufferData is false on host side, in case when we're taking snapshot
782 after state load and before this context was ever made current*/
783 CRASSERT(pBufferObj->size>0);
784 rc = SSMR3PutMem(pSSM, pBufferObj->data, pBufferObj->size);
785 CRASSERT(rc == VINF_SUCCESS);
786 }
787 else if (pBufferObj->id!=0 && pBufferObj->size>0)
788 {
789 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, pBufferObj->hwid);
790 pBufferObj->pointer = diff_api.MapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_ONLY_ARB);
791 rc = SSMR3PutMem(pSSM, &pBufferObj->pointer, sizeof(pBufferObj->pointer));
792 CRASSERT(rc == VINF_SUCCESS);
793 if (pBufferObj->pointer)
794 {
795 rc = SSMR3PutMem(pSSM, pBufferObj->pointer, pBufferObj->size);
796 CRASSERT(rc == VINF_SUCCESS);
797 }
798 diff_api.UnmapBufferARB(GL_ARRAY_BUFFER_ARB);
799 pBufferObj->pointer = NULL;
800 }
801}
802
803static void crStateSaveProgramCB(unsigned long key, void *data1, void *data2)
804{
805 CRProgram *pProgram = (CRProgram *) data1;
806 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
807 CRProgramSymbol *pSymbol;
808 int32_t rc;
809
810 CRASSERT(pProgram && pSSM);
811
812 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
813 CRASSERT(rc == VINF_SUCCESS);
814 rc = SSMR3PutMem(pSSM, pProgram, sizeof(*pProgram));
815 CRASSERT(rc == VINF_SUCCESS);
816 if (pProgram->string)
817 {
818 CRASSERT(pProgram->length);
819 rc = SSMR3PutMem(pSSM, pProgram->string, pProgram->length);
820 CRASSERT(rc == VINF_SUCCESS);
821 }
822
823 for (pSymbol = pProgram->symbolTable; pSymbol; pSymbol=pSymbol->next)
824 {
825 rc = SSMR3PutMem(pSSM, pSymbol, sizeof(*pSymbol));
826 CRASSERT(rc == VINF_SUCCESS);
827 if (pSymbol->name)
828 {
829 CRASSERT(pSymbol->cbName>0);
830 rc = SSMR3PutMem(pSSM, pSymbol->name, pSymbol->cbName);
831 CRASSERT(rc == VINF_SUCCESS);
832 }
833 }
834}
835
836static void crStateSaveFramebuffersCB(unsigned long key, void *data1, void *data2)
837{
838 CRFramebufferObject *pFBO = (CRFramebufferObject*) data1;
839 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
840 int32_t rc;
841
842 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
843 CRASSERT(rc == VINF_SUCCESS);
844
845 rc = SSMR3PutMem(pSSM, pFBO, sizeof(*pFBO));
846 CRASSERT(rc == VINF_SUCCESS);
847}
848
849static void crStateSaveRenderbuffersCB(unsigned long key, void *data1, void *data2)
850{
851 CRRenderbufferObject *pRBO = (CRRenderbufferObject*) data1;
852 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
853 int32_t rc;
854
855 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
856 CRASSERT(rc == VINF_SUCCESS);
857
858 rc = SSMR3PutMem(pSSM, pRBO, sizeof(*pRBO));
859 CRASSERT(rc == VINF_SUCCESS);
860}
861
862static int32_t crStateLoadProgram(CRProgram **ppProgram, PSSMHANDLE pSSM)
863{
864 CRProgramSymbol **ppSymbol;
865 int32_t rc;
866 unsigned long key;
867
868 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
869 AssertRCReturn(rc, rc);
870
871 /* we're loading default vertex or pixel program*/
872 if (*ppProgram)
873 {
874 if (key!=0) return VERR_SSM_UNEXPECTED_DATA;
875 }
876 else
877 {
878 *ppProgram = (CRProgram*) crAlloc(sizeof(CRProgram));
879 if (!ppProgram) return VERR_NO_MEMORY;
880 if (key==0) return VERR_SSM_UNEXPECTED_DATA;
881 }
882
883 rc = SSMR3GetMem(pSSM, *ppProgram, sizeof(**ppProgram));
884 AssertRCReturn(rc, rc);
885
886 if ((*ppProgram)->string)
887 {
888 CRASSERT((*ppProgram)->length);
889 (*ppProgram)->string = crAlloc((*ppProgram)->length);
890 if (!(*ppProgram)->string) return VERR_NO_MEMORY;
891 rc = SSMR3GetMem(pSSM, (void*) (*ppProgram)->string, (*ppProgram)->length);
892 AssertRCReturn(rc, rc);
893 }
894
895 for (ppSymbol = &(*ppProgram)->symbolTable; *ppSymbol; ppSymbol=&(*ppSymbol)->next)
896 {
897 *ppSymbol = crAlloc(sizeof(CRProgramSymbol));
898 if (!ppSymbol) return VERR_NO_MEMORY;
899
900 rc = SSMR3GetMem(pSSM, *ppSymbol, sizeof(**ppSymbol));
901 AssertRCReturn(rc, rc);
902
903 if ((*ppSymbol)->name)
904 {
905 CRASSERT((*ppSymbol)->cbName>0);
906 (*ppSymbol)->name = crAlloc((*ppSymbol)->cbName);
907 if (!(*ppSymbol)->name) return VERR_NO_MEMORY;
908
909 rc = SSMR3GetMem(pSSM, (void*) (*ppSymbol)->name, (*ppSymbol)->cbName);
910 AssertRCReturn(rc, rc);
911 }
912 }
913
914 return VINF_SUCCESS;
915}
916
917static void crStateSaveString(const char *pStr, PSSMHANDLE pSSM)
918{
919 int32_t len;
920 int32_t rc;
921
922 if (pStr)
923 {
924 len = crStrlen(pStr)+1;
925
926 rc = SSMR3PutS32(pSSM, len);
927 CRASSERT(rc == VINF_SUCCESS);
928
929 rc = SSMR3PutMem(pSSM, pStr, len*sizeof(*pStr));
930 CRASSERT(rc == VINF_SUCCESS);
931 }
932 else
933 {
934 rc = SSMR3PutS32(pSSM, 0);
935 CRASSERT(rc == VINF_SUCCESS);
936 }
937}
938
939static char* crStateLoadString(PSSMHANDLE pSSM)
940{
941 int32_t len, rc;
942 char* pStr = NULL;
943
944 rc = SSMR3GetS32(pSSM, &len);
945 CRASSERT(rc == VINF_SUCCESS);
946
947 if (len!=0)
948 {
949 pStr = crAlloc(len*sizeof(*pStr));
950
951 rc = SSMR3GetMem(pSSM, pStr, len*sizeof(*pStr));
952 CRASSERT(rc == VINF_SUCCESS);
953 }
954
955 return pStr;
956}
957
958static void crStateSaveGLSLShaderCB(unsigned long key, void *data1, void *data2)
959{
960 CRGLSLShader *pShader = (CRGLSLShader*) data1;
961 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
962 int32_t rc;
963
964 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
965 CRASSERT(rc == VINF_SUCCESS);
966
967 rc = SSMR3PutMem(pSSM, pShader, sizeof(*pShader));
968 CRASSERT(rc == VINF_SUCCESS);
969
970 if (pShader->source)
971 {
972 crStateSaveString(pShader->source, pSSM);
973 }
974 else
975 {
976 GLint sLen=0;
977 GLchar *source=NULL;
978
979 diff_api.GetShaderiv(pShader->hwid, GL_SHADER_SOURCE_LENGTH, &sLen);
980 if (sLen>0)
981 {
982 source = (GLchar*) crAlloc(sLen);
983 diff_api.GetShaderSource(pShader->hwid, sLen, NULL, source);
984 }
985
986 crStateSaveString(source, pSSM);
987 if (source) crFree(source);
988 }
989}
990
991static CRGLSLShader* crStateLoadGLSLShader(PSSMHANDLE pSSM)
992{
993 CRGLSLShader *pShader;
994 int32_t rc;
995 unsigned long key;
996
997 pShader = crAlloc(sizeof(*pShader));
998 if (!pShader) return NULL;
999
1000 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
1001 CRASSERT(rc == VINF_SUCCESS);
1002
1003 rc = SSMR3GetMem(pSSM, pShader, sizeof(*pShader));
1004 CRASSERT(rc == VINF_SUCCESS);
1005
1006 pShader->source = crStateLoadString(pSSM);
1007
1008 return pShader;
1009}
1010
1011
1012static void crStateSaveGLSLShaderKeyCB(unsigned long key, void *data1, void *data2)
1013{
1014 CRGLSLShader *pShader = (CRGLSLShader*) data1;
1015 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
1016 int32_t rc;
1017
1018 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
1019 CRASSERT(rc == VINF_SUCCESS);
1020}
1021
1022static void crStateSaveGLSLProgramAttribs(CRGLSLProgramState *pState, PSSMHANDLE pSSM)
1023{
1024 GLuint i;
1025 int32_t rc;
1026
1027 for (i=0; i<pState->cAttribs; ++i)
1028 {
1029 rc = SSMR3PutMem(pSSM, &pState->pAttribs[i].index, sizeof(pState->pAttribs[i].index));
1030 CRASSERT(rc == VINF_SUCCESS);
1031 crStateSaveString(pState->pAttribs[i].name, pSSM);
1032 }
1033}
1034
1035static void crStateSaveGLSLProgramCB(unsigned long key, void *data1, void *data2)
1036{
1037 CRGLSLProgram *pProgram = (CRGLSLProgram*) data1;
1038 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
1039 int32_t rc;
1040 uint32_t ui32;
1041 GLint maxUniformLen, activeUniforms=0, uniformsCount=0, i, j;
1042 GLchar *name = NULL;
1043 GLenum type;
1044 GLint size, location;
1045
1046 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
1047 CRASSERT(rc == VINF_SUCCESS);
1048
1049 rc = SSMR3PutMem(pSSM, pProgram, sizeof(*pProgram));
1050 CRASSERT(rc == VINF_SUCCESS);
1051
1052 ui32 = crHashtableNumElements(pProgram->currentState.attachedShaders);
1053 rc = SSMR3PutU32(pSSM, ui32);
1054 CRASSERT(rc == VINF_SUCCESS);
1055
1056 crHashtableWalk(pProgram->currentState.attachedShaders, crStateSaveGLSLShaderKeyCB, pSSM);
1057
1058 if (pProgram->activeState.attachedShaders)
1059 {
1060 ui32 = crHashtableNumElements(pProgram->activeState.attachedShaders);
1061 rc = SSMR3PutU32(pSSM, ui32);
1062 CRASSERT(rc == VINF_SUCCESS);
1063 crHashtableWalk(pProgram->currentState.attachedShaders, crStateSaveGLSLShaderCB, pSSM);
1064 }
1065
1066 crStateSaveGLSLProgramAttribs(&pProgram->currentState, pSSM);
1067 crStateSaveGLSLProgramAttribs(&pProgram->activeState, pSSM);
1068
1069 diff_api.GetProgramiv(pProgram->hwid, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformLen);
1070 diff_api.GetProgramiv(pProgram->hwid, GL_ACTIVE_UNIFORMS, &activeUniforms);
1071
1072 if (activeUniforms>0)
1073 {
1074 name = (GLchar *) crAlloc((maxUniformLen+8)*sizeof(GLchar));
1075
1076 if (!name)
1077 {
1078 crWarning("crStateSaveGLSLProgramCB: out of memory");
1079 return;
1080 }
1081 }
1082
1083 for (i=0; i<activeUniforms; ++i)
1084 {
1085 diff_api.GetActiveUniform(pProgram->hwid, i, maxUniformLen, NULL, &size, &type, name);
1086 uniformsCount += size;
1087 }
1088 CRASSERT(uniformsCount>=activeUniforms);
1089
1090 rc = SSMR3PutS32(pSSM, uniformsCount);
1091 CRASSERT(rc == VINF_SUCCESS);
1092
1093 if (activeUniforms>0)
1094 {
1095 GLfloat fdata[16];
1096 GLint idata[16];
1097 char *pIndexStr=NULL;
1098
1099 for (i=0; i<activeUniforms; ++i)
1100 {
1101 diff_api.GetActiveUniform(pProgram->hwid, i, maxUniformLen, NULL, &size, &type, name);
1102
1103 if (size>1)
1104 {
1105 pIndexStr = crStrchr(name, '[');
1106 if (!pIndexStr)
1107 {
1108 pIndexStr = name+crStrlen(name);
1109 }
1110 }
1111
1112 for (j=0; j<size; ++j)
1113 {
1114 if (size>1)
1115 {
1116 sprintf(pIndexStr, "[%i]", j);
1117 }
1118 location = diff_api.GetUniformLocation(pProgram->hwid, name);
1119
1120 rc = SSMR3PutMem(pSSM, &type, sizeof(type));
1121 CRASSERT(rc == VINF_SUCCESS);
1122
1123 crStateSaveString(name, pSSM);
1124
1125 if (crStateIsIntUniform(type))
1126 {
1127 diff_api.GetUniformiv(pProgram->hwid, location, &idata[0]);
1128 rc = SSMR3PutMem(pSSM, &idata[0], crStateGetUniformSize(type)*sizeof(idata[0]));
1129 CRASSERT(rc == VINF_SUCCESS);
1130 }
1131 else
1132 {
1133 diff_api.GetUniformfv(pProgram->hwid, location, &fdata[0]);
1134 rc = SSMR3PutMem(pSSM, &fdata[0], crStateGetUniformSize(type)*sizeof(fdata[0]));
1135 CRASSERT(rc == VINF_SUCCESS);
1136 }
1137 }
1138 }
1139
1140 crFree(name);
1141 }
1142}
1143
1144static int32_t crStateSaveClientPointer(CRVertexArrays *pArrays, int32_t index, PSSMHANDLE pSSM)
1145{
1146 int32_t rc;
1147 CRClientPointer *cp;
1148
1149 cp = crStateGetClientPointerByIndex(index, pArrays);
1150
1151 if (cp->buffer)
1152 rc = SSMR3PutU32(pSSM, cp->buffer->id);
1153 else
1154 rc = SSMR3PutU32(pSSM, 0);
1155
1156 AssertRCReturn(rc, rc);
1157
1158#ifdef CR_EXT_compiled_vertex_array
1159 if (cp->locked)
1160 {
1161 CRASSERT(cp->p);
1162 rc = SSMR3PutMem(pSSM, cp->p, cp->stride*(pArrays->lockFirst+pArrays->lockCount));
1163 AssertRCReturn(rc, rc);
1164 }
1165#endif
1166
1167 return VINF_SUCCESS;
1168}
1169
1170static int32_t crStateLoadClientPointer(CRVertexArrays *pArrays, int32_t index, CRContext *pContext, PSSMHANDLE pSSM)
1171{
1172 int32_t rc;
1173 uint32_t ui;
1174 CRClientPointer *cp;
1175
1176 cp = crStateGetClientPointerByIndex(index, pArrays);
1177
1178 rc = SSMR3GetU32(pSSM, &ui);
1179 AssertRCReturn(rc, rc);
1180 cp->buffer = ui==0 ? pContext->bufferobject.nullBuffer : crHashtableSearch(pContext->shared->buffersTable, ui);
1181
1182 if (!cp->buffer)
1183 {
1184 crWarning("crStateLoadClientPointer: ui=%d loaded as NULL buffer!", ui);
1185 }
1186
1187#ifdef CR_EXT_compiled_vertex_array
1188 if (cp->locked)
1189 {
1190 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&cp->p, cp->stride*(pArrays->lockFirst+pArrays->lockCount));
1191 AssertRCReturn(rc, rc);
1192 }
1193#endif
1194
1195 return VINF_SUCCESS;
1196}
1197
1198static int32_t crStateSaveCurrentBits(CRStateBits *pBits, PSSMHANDLE pSSM)
1199{
1200 int32_t rc, i;
1201
1202 rc = SSMR3PutMem(pSSM, pBits, sizeof(*pBits));
1203 AssertRCReturn(rc, rc);
1204
1205 rc = SSMR3PutMem(pSSM, pBits->client.v, GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1206 AssertRCReturn(rc, rc);
1207 rc = SSMR3PutMem(pSSM, pBits->client.n, GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1208 AssertRCReturn(rc, rc);
1209 rc = SSMR3PutMem(pSSM, pBits->client.c, GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1210 AssertRCReturn(rc, rc);
1211 rc = SSMR3PutMem(pSSM, pBits->client.s, GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1212 AssertRCReturn(rc, rc);
1213 rc = SSMR3PutMem(pSSM, pBits->client.i, GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1214 AssertRCReturn(rc, rc);
1215 for (i=0; i<CR_MAX_TEXTURE_UNITS; i++)
1216 {
1217 rc = SSMR3PutMem(pSSM, pBits->client.t[i], GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1218 AssertRCReturn(rc, rc);
1219 }
1220 rc = SSMR3PutMem(pSSM, pBits->client.e, GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1221 AssertRCReturn(rc, rc);
1222 rc = SSMR3PutMem(pSSM, pBits->client.f, GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1223 AssertRCReturn(rc, rc);
1224#ifdef CR_NV_vertex_program
1225 for (i=0; i<CR_MAX_VERTEX_ATTRIBS; i++)
1226 {
1227 rc = SSMR3PutMem(pSSM, pBits->client.a[i], GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1228 AssertRCReturn(rc, rc);
1229 }
1230#endif
1231
1232 rc = SSMR3PutMem(pSSM, pBits->lighting.light, CR_MAX_LIGHTS*sizeof(pBits->lighting.light));
1233 AssertRCReturn(rc, rc);
1234
1235 return VINF_SUCCESS;
1236}
1237
1238static int32_t crStateLoadCurrentBits(CRStateBits *pBits, PSSMHANDLE pSSM)
1239{
1240 int32_t rc, i;
1241 CRClientBits client;
1242 CRLightingBits lighting;
1243
1244 CRASSERT(pBits);
1245
1246 client.v = pBits->client.v;
1247 client.n = pBits->client.n;
1248 client.c = pBits->client.c;
1249 client.s = pBits->client.s;
1250 client.i = pBits->client.i;
1251 client.e = pBits->client.e;
1252 client.f = pBits->client.f;
1253 for (i=0; i<CR_MAX_TEXTURE_UNITS; i++)
1254 {
1255 client.t[i] = pBits->client.t[i];
1256 }
1257#ifdef CR_NV_vertex_program
1258 for (i=0; i<CR_MAX_VERTEX_ATTRIBS; i++)
1259 {
1260 client.a[i] = pBits->client.a[i];
1261 }
1262#endif
1263 lighting.light = pBits->lighting.light;
1264
1265 rc = SSMR3GetMem(pSSM, pBits, sizeof(*pBits));
1266 AssertRCReturn(rc, rc);
1267
1268 pBits->client.v = client.v;
1269 rc = SSMR3GetMem(pSSM, pBits->client.v, GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1270 AssertRCReturn(rc, rc);
1271 pBits->client.n = client.n;
1272 rc = SSMR3GetMem(pSSM, pBits->client.n, GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1273 AssertRCReturn(rc, rc);
1274 pBits->client.c = client.c;
1275 rc = SSMR3GetMem(pSSM, pBits->client.c, GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1276 AssertRCReturn(rc, rc);
1277 pBits->client.s = client.s;
1278 rc = SSMR3GetMem(pSSM, pBits->client.s, GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1279 AssertRCReturn(rc, rc);
1280 pBits->client.i = client.i;
1281 rc = SSMR3GetMem(pSSM, pBits->client.i, GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1282 AssertRCReturn(rc, rc);
1283 pBits->client.e = client.e;
1284 rc = SSMR3GetMem(pSSM, pBits->client.e, GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1285 AssertRCReturn(rc, rc);
1286 pBits->client.f = client.f;
1287 rc = SSMR3GetMem(pSSM, pBits->client.f, GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1288 AssertRCReturn(rc, rc);
1289 for (i=0; i<CR_MAX_TEXTURE_UNITS; i++)
1290 {
1291 pBits->client.t[i] = client.t[i];
1292 rc = SSMR3GetMem(pSSM, pBits->client.t[i], GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1293 AssertRCReturn(rc, rc);
1294 }
1295#ifdef CR_NV_vertex_program
1296 for (i=0; i<CR_MAX_VERTEX_ATTRIBS; i++)
1297 {
1298 pBits->client.a[i] = client.a[i];
1299 rc = SSMR3GetMem(pSSM, pBits->client.a[i], GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
1300 AssertRCReturn(rc, rc);
1301 }
1302#endif
1303
1304 pBits->lighting.light = lighting.light;
1305 rc = SSMR3GetMem(pSSM, pBits->lighting.light, CR_MAX_LIGHTS*sizeof(pBits->lighting.light));
1306 AssertRCReturn(rc, rc);
1307
1308 return VINF_SUCCESS;
1309}
1310
1311int32_t crStateSaveContext(CRContext *pContext, PSSMHANDLE pSSM)
1312{
1313 int32_t rc, i;
1314 uint32_t ui32, j;
1315 GLboolean bSaveShared = GL_TRUE;
1316
1317 CRASSERT(pContext && pSSM);
1318
1319 pContext->buffer.storedWidth = pContext->buffer.width;
1320 pContext->buffer.storedHeight = pContext->buffer.height;
1321
1322 CRASSERT(VBoxTlsRefIsFunctional(pContext));
1323
1324 /* do not increment the saved state version due to VBOXTLSREFDATA addition to CRContext */
1325 rc = SSMR3PutMem(pSSM, pContext, VBOXTLSREFDATA_OFFSET(CRContext));
1326 AssertRCReturn(rc, rc);
1327
1328 /* now store bitid & neg_bitid */
1329 rc = SSMR3PutMem(pSSM, pContext->bitid, sizeof (pContext->bitid) + sizeof (pContext->neg_bitid));
1330 AssertRCReturn(rc, rc);
1331
1332 /* the pre-VBOXTLSREFDATA CRContext structure might have additional allignment bits before the CRContext::shared */
1333 ui32 = VBOXTLSREFDATA_OFFSET(CRContext) + sizeof (pContext->bitid) + sizeof (pContext->neg_bitid);
1334 ui32 &= (sizeof (void*) - 1);
1335 if (ui32)
1336 {
1337 void* pTmp = NULL;
1338 rc = SSMR3PutMem(pSSM, &pTmp, ui32);
1339 AssertRCReturn(rc, rc);
1340 }
1341
1342 rc = SSMR3PutMem(pSSM, &pContext->shared, sizeof (CRContext) - RT_OFFSETOF(CRContext, shared));
1343 AssertRCReturn(rc, rc);
1344
1345 if (crHashtableNumElements(pContext->shared->dlistTable)>0)
1346 crWarning("Saving state with %d display lists, unsupported", crHashtableNumElements(pContext->shared->dlistTable));
1347
1348 if (crHashtableNumElements(pContext->program.programHash)>0)
1349 crDebug("Saving state with %d programs", crHashtableNumElements(pContext->program.programHash));
1350
1351 rc = SSMR3PutS32(pSSM, pContext->shared->id);
1352 AssertRCReturn(rc, rc);
1353
1354 rc = SSMR3PutS32(pSSM, crStateContextIsShared(pContext));
1355 AssertRCReturn(rc, rc);
1356
1357 if (pContext->shared->refCount>1)
1358 {
1359 bSaveShared = pContext->shared->saveCount==0;
1360
1361 ++pContext->shared->saveCount;
1362 if (pContext->shared->saveCount == pContext->shared->refCount)
1363 {
1364 pContext->shared->saveCount=0;
1365 }
1366 }
1367
1368 /* Save transform state */
1369 rc = SSMR3PutMem(pSSM, pContext->transform.clipPlane, sizeof(GLvectord)*CR_MAX_CLIP_PLANES);
1370 AssertRCReturn(rc, rc);
1371 rc = SSMR3PutMem(pSSM, pContext->transform.clip, sizeof(GLboolean)*CR_MAX_CLIP_PLANES);
1372 AssertRCReturn(rc, rc);
1373 rc = crStateSaveMatrixStack(&pContext->transform.modelViewStack, pSSM);
1374 AssertRCReturn(rc, rc);
1375 rc = crStateSaveMatrixStack(&pContext->transform.projectionStack, pSSM);
1376 AssertRCReturn(rc, rc);
1377 rc = crStateSaveMatrixStack(&pContext->transform.colorStack, pSSM);
1378 AssertRCReturn(rc, rc);
1379 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
1380 {
1381 rc = crStateSaveMatrixStack(&pContext->transform.textureStack[i], pSSM);
1382 AssertRCReturn(rc, rc);
1383 }
1384 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
1385 {
1386 rc = crStateSaveMatrixStack(&pContext->transform.programStack[i], pSSM);
1387 AssertRCReturn(rc, rc);
1388 }
1389
1390 /* Save textures */
1391 rc = crStateSaveTextureObjData(&pContext->texture.base1D, pSSM);
1392 AssertRCReturn(rc, rc);
1393 rc = crStateSaveTextureObjData(&pContext->texture.base2D, pSSM);
1394 AssertRCReturn(rc, rc);
1395 rc = crStateSaveTextureObjData(&pContext->texture.base3D, pSSM);
1396 AssertRCReturn(rc, rc);
1397 rc = crStateSaveTextureObjData(&pContext->texture.proxy1D, pSSM);
1398 AssertRCReturn(rc, rc);
1399 rc = crStateSaveTextureObjData(&pContext->texture.proxy2D, pSSM);
1400 AssertRCReturn(rc, rc);
1401 rc = crStateSaveTextureObjData(&pContext->texture.proxy3D, pSSM);
1402#ifdef CR_ARB_texture_cube_map
1403 rc = crStateSaveTextureObjData(&pContext->texture.baseCubeMap, pSSM);
1404 AssertRCReturn(rc, rc);
1405 rc = crStateSaveTextureObjData(&pContext->texture.proxyCubeMap, pSSM);
1406 AssertRCReturn(rc, rc);
1407#endif
1408#ifdef CR_NV_texture_rectangle
1409 rc = crStateSaveTextureObjData(&pContext->texture.baseRect, pSSM);
1410 AssertRCReturn(rc, rc);
1411 rc = crStateSaveTextureObjData(&pContext->texture.proxyRect, pSSM);
1412 AssertRCReturn(rc, rc);
1413#endif
1414
1415 /* Save shared textures */
1416 if (bSaveShared)
1417 {
1418 CRASSERT(pContext->shared && pContext->shared->textureTable);
1419 ui32 = crHashtableNumElements(pContext->shared->textureTable);
1420 rc = SSMR3PutU32(pSSM, ui32);
1421 AssertRCReturn(rc, rc);
1422 crHashtableWalk(pContext->shared->textureTable, crStateSaveSharedTextureCB, pSSM);
1423
1424#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
1425 /* Restore previous texture bindings via diff_api */
1426 if (ui32)
1427 {
1428 CRTextureUnit *pTexUnit;
1429
1430 pTexUnit = &pContext->texture.unit[pContext->texture.curTextureUnit];
1431
1432 diff_api.BindTexture(GL_TEXTURE_1D, pTexUnit->currentTexture1D->hwid);
1433 diff_api.BindTexture(GL_TEXTURE_2D, pTexUnit->currentTexture2D->hwid);
1434 diff_api.BindTexture(GL_TEXTURE_3D, pTexUnit->currentTexture3D->hwid);
1435#ifdef CR_ARB_texture_cube_map
1436 diff_api.BindTexture(GL_TEXTURE_CUBE_MAP_ARB, pTexUnit->currentTextureCubeMap->hwid);
1437#endif
1438#ifdef CR_NV_texture_rectangle
1439 diff_api.BindTexture(GL_TEXTURE_RECTANGLE_NV, pTexUnit->currentTextureRect->hwid);
1440#endif
1441 }
1442#endif
1443 }
1444
1445 /* Save current texture pointers */
1446 for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
1447 {
1448 rc = crStateSaveTexUnitCurrentTexturePtrs(&pContext->texture.unit[i], pSSM);
1449 AssertRCReturn(rc, rc);
1450 }
1451
1452 /* Save lights */
1453 CRASSERT(pContext->lighting.light);
1454 rc = SSMR3PutMem(pSSM, pContext->lighting.light, CR_MAX_LIGHTS * sizeof(*pContext->lighting.light));
1455 AssertRCReturn(rc, rc);
1456
1457 /* Save attrib stack*/
1458 /*@todo could go up to used stack depth here?*/
1459 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
1460 {
1461 if (pContext->attrib.enableStack[i].clip)
1462 {
1463 rc = SSMR3PutMem(pSSM, pContext->attrib.enableStack[i].clip,
1464 pContext->limits.maxClipPlanes*sizeof(GLboolean));
1465 AssertRCReturn(rc, rc);
1466 }
1467
1468 if (pContext->attrib.enableStack[i].light)
1469 {
1470 rc = SSMR3PutMem(pSSM, pContext->attrib.enableStack[i].light,
1471 pContext->limits.maxLights*sizeof(GLboolean));
1472 AssertRCReturn(rc, rc);
1473 }
1474
1475 if (pContext->attrib.lightingStack[i].light)
1476 {
1477 rc = SSMR3PutMem(pSSM, pContext->attrib.lightingStack[i].light,
1478 pContext->limits.maxLights*sizeof(CRLight));
1479 AssertRCReturn(rc, rc);
1480 }
1481
1482 for (j=0; j<pContext->limits.maxTextureUnits; ++j)
1483 {
1484 rc = crStateSaveTexUnitCurrentTexturePtrs(&pContext->attrib.textureStack[i].unit[j], pSSM);
1485 AssertRCReturn(rc, rc);
1486 }
1487
1488 if (pContext->attrib.transformStack[i].clip)
1489 {
1490 rc = SSMR3PutMem(pSSM, pContext->attrib.transformStack[i].clip,
1491 pContext->limits.maxClipPlanes*sizeof(GLboolean));
1492 AssertRCReturn(rc, rc);
1493 }
1494
1495 if (pContext->attrib.transformStack[i].clipPlane)
1496 {
1497 rc = SSMR3PutMem(pSSM, pContext->attrib.transformStack[i].clipPlane,
1498 pContext->limits.maxClipPlanes*sizeof(GLvectord));
1499 AssertRCReturn(rc, rc);
1500 }
1501
1502 rc = crSateSaveEvalCoeffs1D(pContext->attrib.evalStack[i].eval1D, pSSM);
1503 AssertRCReturn(rc, rc);
1504 rc = crSateSaveEvalCoeffs2D(pContext->attrib.evalStack[i].eval2D, pSSM);
1505 AssertRCReturn(rc, rc);
1506 }
1507
1508 /* Save evaluator coeffs */
1509 rc = crSateSaveEvalCoeffs1D(pContext->eval.eval1D, pSSM);
1510 AssertRCReturn(rc, rc);
1511 rc = crSateSaveEvalCoeffs2D(pContext->eval.eval2D, pSSM);
1512 AssertRCReturn(rc, rc);
1513
1514#ifdef CR_ARB_vertex_buffer_object
1515 /* Save buffer objects */
1516 ui32 = bSaveShared? crHashtableNumElements(pContext->shared->buffersTable):0;
1517 rc = SSMR3PutU32(pSSM, ui32);
1518 AssertRCReturn(rc, rc);
1519
1520 /* Save default one*/
1521 crStateSaveBufferObjectCB(0, pContext->bufferobject.nullBuffer, pSSM);
1522
1523 if (bSaveShared)
1524 {
1525 /* Save all the rest */
1526 crHashtableWalk(pContext->shared->buffersTable, crStateSaveBufferObjectCB, pSSM);
1527 }
1528
1529 /* Restore binding */
1530 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, pContext->bufferobject.arrayBuffer->hwid);
1531
1532 /* Save pointers */
1533 rc = SSMR3PutU32(pSSM, pContext->bufferobject.arrayBuffer->id);
1534 AssertRCReturn(rc, rc);
1535 rc = SSMR3PutU32(pSSM, pContext->bufferobject.elementsBuffer->id);
1536 AssertRCReturn(rc, rc);
1537#ifdef CR_ARB_pixel_buffer_object
1538 rc = SSMR3PutU32(pSSM, pContext->bufferobject.packBuffer->id);
1539 AssertRCReturn(rc, rc);
1540 rc = SSMR3PutU32(pSSM, pContext->bufferobject.unpackBuffer->id);
1541 AssertRCReturn(rc, rc);
1542#endif
1543 /* Save clint pointers and buffer bindings*/
1544 for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
1545 {
1546 rc = crStateSaveClientPointer(&pContext->client.array, i, pSSM);
1547 AssertRCReturn(rc, rc);
1548 }
1549
1550 crDebug("client.vertexArrayStackDepth %i", pContext->client.vertexArrayStackDepth);
1551 for (i=0; i<pContext->client.vertexArrayStackDepth; ++i)
1552 {
1553 CRVertexArrays *pArray = &pContext->client.vertexArrayStack[i];
1554 for (j=0; j<CRSTATECLIENT_MAX_VERTEXARRAYS; ++j)
1555 {
1556 rc = crStateSaveClientPointer(pArray, j, pSSM);
1557 AssertRCReturn(rc, rc);
1558 }
1559 }
1560#endif /*CR_ARB_vertex_buffer_object*/
1561
1562 /* Save pixel/vertex programs */
1563 ui32 = crHashtableNumElements(pContext->program.programHash);
1564 rc = SSMR3PutU32(pSSM, ui32);
1565 AssertRCReturn(rc, rc);
1566 /* Save defaults programs */
1567 crStateSaveProgramCB(0, pContext->program.defaultVertexProgram, pSSM);
1568 crStateSaveProgramCB(0, pContext->program.defaultFragmentProgram, pSSM);
1569 /* Save all the rest */
1570 crHashtableWalk(pContext->program.programHash, crStateSaveProgramCB, pSSM);
1571 /* Save Pointers */
1572 rc = SSMR3PutU32(pSSM, pContext->program.currentVertexProgram->id);
1573 AssertRCReturn(rc, rc);
1574 rc = SSMR3PutU32(pSSM, pContext->program.currentFragmentProgram->id);
1575 AssertRCReturn(rc, rc);
1576 /* This one is unused it seems*/
1577 CRASSERT(!pContext->program.errorString);
1578
1579#ifdef CR_EXT_framebuffer_object
1580 /* Save FBOs */
1581 if (bSaveShared)
1582 {
1583 ui32 = crHashtableNumElements(pContext->shared->fbTable);
1584 rc = SSMR3PutU32(pSSM, ui32);
1585 AssertRCReturn(rc, rc);
1586 crHashtableWalk(pContext->shared->fbTable, crStateSaveFramebuffersCB, pSSM);
1587 ui32 = crHashtableNumElements(pContext->shared->rbTable);
1588 rc = SSMR3PutU32(pSSM, ui32);
1589 AssertRCReturn(rc, rc);
1590 crHashtableWalk(pContext->shared->rbTable, crStateSaveRenderbuffersCB, pSSM);
1591 }
1592 rc = SSMR3PutU32(pSSM, pContext->framebufferobject.drawFB?pContext->framebufferobject.drawFB->id:0);
1593 AssertRCReturn(rc, rc);
1594 rc = SSMR3PutU32(pSSM, pContext->framebufferobject.readFB?pContext->framebufferobject.readFB->id:0);
1595 AssertRCReturn(rc, rc);
1596 rc = SSMR3PutU32(pSSM, pContext->framebufferobject.renderbuffer?pContext->framebufferobject.renderbuffer->id:0);
1597 AssertRCReturn(rc, rc);
1598#endif
1599
1600#ifdef CR_OPENGL_VERSION_2_0
1601 /* Save GLSL related info */
1602 ui32 = crHashtableNumElements(pContext->glsl.shaders);
1603 rc = SSMR3PutU32(pSSM, ui32);
1604 AssertRCReturn(rc, rc);
1605 crHashtableWalk(pContext->glsl.shaders, crStateSaveGLSLShaderCB, pSSM);
1606 ui32 = crHashtableNumElements(pContext->glsl.programs);
1607 rc = SSMR3PutU32(pSSM, ui32);
1608 AssertRCReturn(rc, rc);
1609 crHashtableWalk(pContext->glsl.programs, crStateSaveGLSLProgramCB, pSSM);
1610 rc = SSMR3PutU32(pSSM, pContext->glsl.activeProgram?pContext->glsl.activeProgram->id:0);
1611 AssertRCReturn(rc, rc);
1612#endif
1613
1614 if (pContext->buffer.storedWidth && pContext->buffer.storedHeight)
1615 {
1616 CRBufferState *pBuf = &pContext->buffer;
1617 CRPixelPackState packing = pContext->client.pack;
1618 GLint cbData;
1619 void *pData;
1620
1621 cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * pBuf->storedWidth * pBuf->storedHeight;
1622 pData = crAlloc(cbData);
1623
1624 if (!pData)
1625 {
1626 return VERR_NO_MEMORY;
1627 }
1628
1629 diff_api.PixelStorei(GL_PACK_SKIP_ROWS, 0);
1630 diff_api.PixelStorei(GL_PACK_SKIP_PIXELS, 0);
1631 diff_api.PixelStorei(GL_PACK_ALIGNMENT, 1);
1632 diff_api.PixelStorei(GL_PACK_ROW_LENGTH, 0);
1633 diff_api.PixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
1634 diff_api.PixelStorei(GL_PACK_SKIP_IMAGES, 0);
1635 diff_api.PixelStorei(GL_PACK_SWAP_BYTES, 0);
1636 diff_api.PixelStorei(GL_PACK_LSB_FIRST, 0);
1637
1638 if (pContext->framebufferobject.readFB)
1639 {
1640 diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, 0);
1641 }
1642 if (pContext->bufferobject.packBuffer->hwid>0)
1643 {
1644 diff_api.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
1645 }
1646
1647 diff_api.ReadBuffer(GL_FRONT);
1648 diff_api.ReadPixels(0, 0, pBuf->storedWidth, pBuf->storedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pData);
1649 rc = SSMR3PutMem(pSSM, pData, cbData);
1650 AssertRCReturn(rc, rc);
1651
1652 diff_api.ReadBuffer(GL_BACK);
1653 diff_api.ReadPixels(0, 0, pBuf->storedWidth, pBuf->storedHeight, GL_RGBA, GL_UNSIGNED_BYTE, pData);
1654 rc = SSMR3PutMem(pSSM, pData, cbData);
1655 AssertRCReturn(rc, rc);
1656
1657 if (pContext->bufferobject.packBuffer->hwid>0)
1658 {
1659 diff_api.BindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pContext->bufferobject.packBuffer->hwid);
1660 }
1661 if (pContext->framebufferobject.readFB)
1662 {
1663 diff_api.BindFramebufferEXT(GL_READ_FRAMEBUFFER, pContext->framebufferobject.readFB->hwid);
1664 }
1665 diff_api.ReadBuffer(pContext->framebufferobject.readFB ?
1666 pContext->framebufferobject.readFB->readbuffer : pContext->buffer.readBuffer);
1667
1668 diff_api.PixelStorei(GL_PACK_SKIP_ROWS, packing.skipRows);
1669 diff_api.PixelStorei(GL_PACK_SKIP_PIXELS, packing.skipPixels);
1670 diff_api.PixelStorei(GL_PACK_ALIGNMENT, packing.alignment);
1671 diff_api.PixelStorei(GL_PACK_ROW_LENGTH, packing.rowLength);
1672 diff_api.PixelStorei(GL_PACK_IMAGE_HEIGHT, packing.imageHeight);
1673 diff_api.PixelStorei(GL_PACK_SKIP_IMAGES, packing.skipImages);
1674 diff_api.PixelStorei(GL_PACK_SWAP_BYTES, packing.swapBytes);
1675 diff_api.PixelStorei(GL_PACK_LSB_FIRST, packing.psLSBFirst);
1676
1677 crFree(pData);
1678 }
1679
1680 return VINF_SUCCESS;
1681}
1682
1683typedef struct _crFindSharedCtxParms {
1684 PFNCRSTATE_CONTEXT_GET pfnCtxGet;
1685 CRContext *pSrcCtx, *pDstCtx;
1686} crFindSharedCtxParms_t;
1687
1688static void crStateFindSharedCB(unsigned long key, void *data1, void *data2)
1689{
1690 crFindSharedCtxParms_t *pParms = (crFindSharedCtxParms_t *) data2;
1691 CRContext *pContext = pParms->pfnCtxGet(data1);
1692 (void) key;
1693
1694 if (pContext!=pParms->pSrcCtx && pContext->shared->id==pParms->pSrcCtx->shared->id)
1695 {
1696 pParms->pDstCtx->shared = pContext->shared;
1697 }
1698}
1699
1700#define SLC_COPYPTR(ptr) pTmpContext->ptr = pContext->ptr
1701#define SLC_ASSSERT_NULL_PTR(ptr) CRASSERT(!pContext->ptr)
1702
1703AssertCompile(VBOXTLSREFDATA_SIZE() <= CR_MAX_BITARRAY);
1704AssertCompile(VBOXTLSREFDATA_STATE_INITIALIZED != 0);
1705AssertCompile(RT_OFFSETOF(CRContext, shared) >= VBOXTLSREFDATA_OFFSET(CRContext) + VBOXTLSREFDATA_SIZE() + RT_SIZEOFMEMB(CRContext, bitid) + RT_SIZEOFMEMB(CRContext, neg_bitid));
1706
1707int32_t crStateLoadContext(CRContext *pContext, CRHashTable * pCtxTable, PFNCRSTATE_CONTEXT_GET pfnCtxGet, PSSMHANDLE pSSM, uint32_t u32Version)
1708{
1709 CRContext* pTmpContext;
1710 int32_t rc, i, j;
1711 uint32_t uiNumElems, ui, k;
1712 unsigned long key;
1713 GLboolean bLoadShared = GL_TRUE;
1714 union {
1715 CRbitvalue bitid[CR_MAX_BITARRAY];
1716 struct {
1717 VBOXTLSREFDATA
1718 } tlsRef;
1719 } bitid;
1720
1721 CRASSERT(pContext && pSSM);
1722
1723 /* This one is rather big for stack allocation and causes macs to crash */
1724 pTmpContext = (CRContext*)crAlloc(sizeof(*pTmpContext));
1725 if (!pTmpContext)
1726 return VERR_NO_MEMORY;
1727
1728 CRASSERT(VBoxTlsRefIsFunctional(pContext));
1729
1730 /* do not increment the saved state version due to VBOXTLSREFDATA addition to CRContext */
1731 rc = SSMR3GetMem(pSSM, pTmpContext, VBOXTLSREFDATA_OFFSET(CRContext));
1732 AssertRCReturn(rc, rc);
1733
1734 /* VBox 4.1.8 had a bug that VBOXTLSREFDATA was also stored in the snapshot,
1735 * thus the saved state data format was changed w/o changing the saved state version.
1736 * here we determine whether the saved state contains VBOXTLSREFDATA, and if so, treat it accordingly */
1737 rc = SSMR3GetMem(pSSM, &bitid, sizeof (bitid));
1738 AssertRCReturn(rc, rc);
1739
1740 /* the bitid array has one bit set only. this is why if bitid.tlsRef has both cTlsRefs
1741 * and enmTlsRefState non-zero - this is definitely NOT a bit id and is a VBOXTLSREFDATA */
1742 if (bitid.tlsRef.enmTlsRefState == VBOXTLSREFDATA_STATE_INITIALIZED
1743 && bitid.tlsRef.cTlsRefs)
1744 {
1745 /* VBOXTLSREFDATA is stored, skip it */
1746 crMemcpy(&pTmpContext->bitid, ((uint8_t*)&bitid) + VBOXTLSREFDATA_SIZE(), sizeof (bitid) - VBOXTLSREFDATA_SIZE());
1747 rc = SSMR3GetMem(pSSM, ((uint8_t*)&pTmpContext->bitid) + sizeof (pTmpContext->bitid) - VBOXTLSREFDATA_SIZE(), sizeof (pTmpContext->neg_bitid) + VBOXTLSREFDATA_SIZE());
1748 AssertRCReturn(rc, rc);
1749
1750 ui = VBOXTLSREFDATA_OFFSET(CRContext) + VBOXTLSREFDATA_SIZE() + sizeof (pTmpContext->bitid) + sizeof (pTmpContext->neg_bitid);
1751 ui = RT_OFFSETOF(CRContext, shared) - ui;
1752 }
1753 else
1754 {
1755 /* VBOXTLSREFDATA is NOT stored */
1756 crMemcpy(&pTmpContext->bitid, &bitid, sizeof (bitid));
1757 rc = SSMR3GetMem(pSSM, &pTmpContext->neg_bitid, sizeof (pTmpContext->neg_bitid));
1758 AssertRCReturn(rc, rc);
1759
1760 /* the pre-VBOXTLSREFDATA CRContext structure might have additional allignment bits before the CRContext::shared */
1761 ui = VBOXTLSREFDATA_OFFSET(CRContext) + sizeof (pTmpContext->bitid) + sizeof (pTmpContext->neg_bitid);
1762
1763 ui &= (sizeof (void*) - 1);
1764 }
1765
1766 if (ui)
1767 {
1768 void* pTmp = NULL;
1769 rc = SSMR3GetMem(pSSM, &pTmp, ui);
1770 AssertRCReturn(rc, rc);
1771 }
1772
1773 /* we will later do crMemcpy from entire pTmpContext to pContext,
1774 * for simplicity store the VBOXTLSREFDATA from the pContext to pTmpContext */
1775 VBOXTLSREFDATA_COPY(pTmpContext, pContext);
1776
1777 if (u32Version == SHCROGL_SSM_VERSION_BEFORE_CTXUSAGE_BITS)
1778 {
1779 SHCROGL_GET_STRUCT_PART(pTmpContext, CRContext, shared, attrib);
1780 rc = crStateLoadAttribState_v_BEFORE_CTXUSAGE_BITS(&pTmpContext->attrib, pSSM);
1781 AssertRCReturn(rc, rc);
1782 SHCROGL_CUT_FIELD_ALIGNMENT(CRContext, attrib, buffer);
1783 SHCROGL_GET_STRUCT_PART(pTmpContext, CRContext, buffer, texture);
1784 rc = crStateLoadTextureState_v_BEFORE_CTXUSAGE_BITS(&pTmpContext->texture, pSSM);
1785 AssertRCReturn(rc, rc);
1786 SHCROGL_CUT_FIELD_ALIGNMENT(CRContext, texture, transform);
1787 SHCROGL_GET_STRUCT_TAIL(pTmpContext, CRContext, transform);
1788 }
1789 else
1790 {
1791 SHCROGL_GET_STRUCT_TAIL(pTmpContext, CRContext, shared);
1792 }
1793
1794 /* Deal with shared state */
1795 {
1796 crFindSharedCtxParms_t parms;
1797 int32_t shared;
1798
1799 rc = SSMR3GetS32(pSSM, &pContext->shared->id);
1800 AssertRCReturn(rc, rc);
1801
1802 rc = SSMR3GetS32(pSSM, &shared);
1803 AssertRCReturn(rc, rc);
1804
1805 pTmpContext->shared = NULL;
1806 parms.pfnCtxGet = pfnCtxGet;
1807 parms.pSrcCtx = pContext;
1808 parms.pDstCtx = pTmpContext;
1809 crHashtableWalk(pCtxTable, crStateFindSharedCB, &parms);
1810
1811 if (pTmpContext->shared)
1812 {
1813 CRASSERT(pContext->shared->refCount==1);
1814 bLoadShared = GL_FALSE;
1815 crStateFreeShared(pContext, pContext->shared);
1816 pContext->shared = NULL;
1817 pTmpContext->shared->refCount++;
1818 }
1819 else
1820 {
1821 SLC_COPYPTR(shared);
1822 }
1823
1824 if (bLoadShared && shared)
1825 {
1826 crStateSetSharedContext(pTmpContext);
1827 }
1828 }
1829
1830 SLC_COPYPTR(flush_func);
1831 SLC_COPYPTR(flush_arg);
1832
1833 /* We're supposed to be loading into an empty context, so those pointers should be NULL */
1834 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
1835 {
1836 SLC_ASSSERT_NULL_PTR(attrib.enableStack[i].clip);
1837 SLC_ASSSERT_NULL_PTR(attrib.enableStack[i].light);
1838
1839 SLC_ASSSERT_NULL_PTR(attrib.lightingStack[i].light);
1840 SLC_ASSSERT_NULL_PTR(attrib.transformStack[i].clip);
1841 SLC_ASSSERT_NULL_PTR(attrib.transformStack[i].clipPlane);
1842
1843 for (j=0; j<GLEVAL_TOT; ++j)
1844 {
1845 SLC_ASSSERT_NULL_PTR(attrib.evalStack[i].eval1D[j].coeff);
1846 SLC_ASSSERT_NULL_PTR(attrib.evalStack[i].eval2D[j].coeff);
1847 }
1848 }
1849
1850#ifdef CR_ARB_vertex_buffer_object
1851 SLC_COPYPTR(bufferobject.nullBuffer);
1852#endif
1853
1854/*@todo, that should be removed probably as those should hold the offset values, so loading should be fine
1855 but better check*/
1856#if 0
1857#ifdef CR_EXT_compiled_vertex_array
1858 SLC_COPYPTR(client.array.v.prevPtr);
1859 SLC_COPYPTR(client.array.c.prevPtr);
1860 SLC_COPYPTR(client.array.f.prevPtr);
1861 SLC_COPYPTR(client.array.s.prevPtr);
1862 SLC_COPYPTR(client.array.e.prevPtr);
1863 SLC_COPYPTR(client.array.i.prevPtr);
1864 SLC_COPYPTR(client.array.n.prevPtr);
1865 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
1866 {
1867 SLC_COPYPTR(client.array.t[i].prevPtr);
1868 }
1869
1870# ifdef CR_NV_vertex_program
1871 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
1872 {
1873 SLC_COPYPTR(client.array.a[i].prevPtr);
1874 }
1875# endif
1876#endif
1877#endif
1878
1879#ifdef CR_ARB_vertex_buffer_object
1880 /*That just sets those pointers to NULL*/
1881 SLC_COPYPTR(client.array.v.buffer);
1882 SLC_COPYPTR(client.array.c.buffer);
1883 SLC_COPYPTR(client.array.f.buffer);
1884 SLC_COPYPTR(client.array.s.buffer);
1885 SLC_COPYPTR(client.array.e.buffer);
1886 SLC_COPYPTR(client.array.i.buffer);
1887 SLC_COPYPTR(client.array.n.buffer);
1888 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
1889 {
1890 SLC_COPYPTR(client.array.t[i].buffer);
1891 }
1892# ifdef CR_NV_vertex_program
1893 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
1894 {
1895 SLC_COPYPTR(client.array.a[i].buffer);
1896 }
1897# endif
1898#endif /*CR_ARB_vertex_buffer_object*/
1899
1900 /*@todo CR_NV_vertex_program*/
1901 crStateCopyEvalPtrs1D(pTmpContext->eval.eval1D, pContext->eval.eval1D);
1902 crStateCopyEvalPtrs2D(pTmpContext->eval.eval2D, pContext->eval.eval2D);
1903
1904 SLC_COPYPTR(feedback.buffer); /*@todo*/
1905 SLC_COPYPTR(selection.buffer); /*@todo*/
1906
1907 SLC_COPYPTR(lighting.light);
1908
1909 /*This one could be tricky if we're loading snapshot on host with different GPU*/
1910 SLC_COPYPTR(limits.extensions);
1911
1912#if CR_ARB_occlusion_query
1913 SLC_COPYPTR(occlusion.objects); /*@todo*/
1914#endif
1915
1916 SLC_COPYPTR(program.errorString);
1917 SLC_COPYPTR(program.programHash);
1918 SLC_COPYPTR(program.defaultVertexProgram);
1919 SLC_COPYPTR(program.defaultFragmentProgram);
1920
1921 /* Texture pointers */
1922 for (i=0; i<6; ++i)
1923 {
1924 SLC_COPYPTR(texture.base1D.level[i]);
1925 SLC_COPYPTR(texture.base2D.level[i]);
1926 SLC_COPYPTR(texture.base3D.level[i]);
1927 SLC_COPYPTR(texture.proxy1D.level[i]);
1928 SLC_COPYPTR(texture.proxy2D.level[i]);
1929 SLC_COPYPTR(texture.proxy3D.level[i]);
1930#ifdef CR_ARB_texture_cube_map
1931 SLC_COPYPTR(texture.baseCubeMap.level[i]);
1932 SLC_COPYPTR(texture.proxyCubeMap.level[i]);
1933#endif
1934#ifdef CR_NV_texture_rectangle
1935 SLC_COPYPTR(texture.baseRect.level[i]);
1936 SLC_COPYPTR(texture.proxyRect.level[i]);
1937#endif
1938 }
1939
1940 /* Load transform state */
1941 SLC_COPYPTR(transform.clipPlane);
1942 SLC_COPYPTR(transform.clip);
1943 /* Don't have to worry about pContext->transform.current as it'd be set in crStateSetCurrent call */
1944 /*SLC_COPYPTR(transform.currentStack);*/
1945 SLC_COPYPTR(transform.modelViewStack.stack);
1946 SLC_COPYPTR(transform.projectionStack.stack);
1947 SLC_COPYPTR(transform.colorStack.stack);
1948
1949 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
1950 {
1951 SLC_COPYPTR(transform.textureStack[i].stack);
1952 }
1953 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
1954 {
1955 SLC_COPYPTR(transform.programStack[i].stack);
1956 }
1957
1958#ifdef CR_OPENGL_VERSION_2_0
1959 SLC_COPYPTR(glsl.shaders);
1960 SLC_COPYPTR(glsl.programs);
1961#endif
1962
1963 /* Have to preserve original context id */
1964 CRASSERT(pTmpContext->id == pContext->id);
1965 CRASSERT(VBOXTLSREFDATA_EQUAL(pContext, pTmpContext));
1966 /* Copy ordinary state to real context */
1967 crMemcpy(pContext, pTmpContext, sizeof(*pTmpContext));
1968 crFree(pTmpContext);
1969 pTmpContext = NULL;
1970
1971 /* Now deal with pointers */
1972
1973 /* Load transform state */
1974 rc = SSMR3GetMem(pSSM, pContext->transform.clipPlane, sizeof(GLvectord)*CR_MAX_CLIP_PLANES);
1975 AssertRCReturn(rc, rc);
1976 rc = SSMR3GetMem(pSSM, pContext->transform.clip, sizeof(GLboolean)*CR_MAX_CLIP_PLANES);
1977 AssertRCReturn(rc, rc);
1978 rc = crStateLoadMatrixStack(&pContext->transform.modelViewStack, pSSM);
1979 AssertRCReturn(rc, rc);
1980 rc = crStateLoadMatrixStack(&pContext->transform.projectionStack, pSSM);
1981 AssertRCReturn(rc, rc);
1982 rc = crStateLoadMatrixStack(&pContext->transform.colorStack, pSSM);
1983 AssertRCReturn(rc, rc);
1984 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
1985 {
1986 rc = crStateLoadMatrixStack(&pContext->transform.textureStack[i], pSSM);
1987 AssertRCReturn(rc, rc);
1988 }
1989 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
1990 {
1991 rc = crStateLoadMatrixStack(&pContext->transform.programStack[i], pSSM);
1992 AssertRCReturn(rc, rc);
1993 }
1994
1995 /* Load Textures */
1996 rc = crStateLoadTextureObjData(&pContext->texture.base1D, pSSM);
1997 AssertRCReturn(rc, rc);
1998 rc = crStateLoadTextureObjData(&pContext->texture.base2D, pSSM);
1999 AssertRCReturn(rc, rc);
2000 rc = crStateLoadTextureObjData(&pContext->texture.base3D, pSSM);
2001 AssertRCReturn(rc, rc);
2002 rc = crStateLoadTextureObjData(&pContext->texture.proxy1D, pSSM);
2003 AssertRCReturn(rc, rc);
2004 rc = crStateLoadTextureObjData(&pContext->texture.proxy2D, pSSM);
2005 AssertRCReturn(rc, rc);
2006 rc = crStateLoadTextureObjData(&pContext->texture.proxy3D, pSSM);
2007 AssertRCReturn(rc, rc);
2008#ifdef CR_ARB_texture_cube_map
2009 rc = crStateLoadTextureObjData(&pContext->texture.baseCubeMap, pSSM);
2010 AssertRCReturn(rc, rc);
2011 rc = crStateLoadTextureObjData(&pContext->texture.proxyCubeMap, pSSM);
2012 AssertRCReturn(rc, rc);
2013#endif
2014#ifdef CR_NV_texture_rectangle
2015 rc = crStateLoadTextureObjData(&pContext->texture.baseRect, pSSM);
2016 AssertRCReturn(rc, rc);
2017 rc = crStateLoadTextureObjData(&pContext->texture.proxyRect, pSSM);
2018 AssertRCReturn(rc, rc);
2019#endif
2020
2021 if (bLoadShared)
2022 {
2023 /* Load shared textures */
2024 CRASSERT(pContext->shared && pContext->shared->textureTable);
2025 rc = SSMR3GetU32(pSSM, &uiNumElems);
2026 AssertRCReturn(rc, rc);
2027 for (ui=0; ui<uiNumElems; ++ui)
2028 {
2029 CRTextureObj *pTexture;
2030
2031 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
2032 AssertRCReturn(rc, rc);
2033
2034 pTexture = (CRTextureObj *) crCalloc(sizeof(CRTextureObj));
2035 if (!pTexture) return VERR_NO_MEMORY;
2036
2037 rc = crStateLoadTextureObj(pTexture, pSSM, u32Version);
2038 AssertRCReturn(rc, rc);
2039
2040 pTexture->hwid = 0;
2041
2042 /*allocate actual memory*/
2043 for (i=0; i<6; ++i) {
2044 pTexture->level[i] = (CRTextureLevel *) crCalloc(sizeof(CRTextureLevel) * CR_MAX_MIPMAP_LEVELS);
2045 if (!pTexture->level[i]) return VERR_NO_MEMORY;
2046 }
2047
2048 rc = crStateLoadTextureObjData(pTexture, pSSM);
2049 AssertRCReturn(rc, rc);
2050
2051 crHashtableAdd(pContext->shared->textureTable, key, pTexture);
2052 }
2053 }
2054
2055 /* Load current texture pointers */
2056 for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
2057 {
2058 rc = crStateLoadTexUnitCurrentTexturePtrs(&pContext->texture.unit[i], pContext, pSSM);
2059 AssertRCReturn(rc, rc);
2060 }
2061
2062 /* Mark textures for resending to GPU */
2063 pContext->shared->bTexResyncNeeded = GL_TRUE;
2064
2065 /* Load lights */
2066 CRASSERT(pContext->lighting.light);
2067 rc = SSMR3GetMem(pSSM, pContext->lighting.light, CR_MAX_LIGHTS * sizeof(*pContext->lighting.light));
2068 AssertRCReturn(rc, rc);
2069
2070 /* Load attrib stack*/
2071 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
2072 {
2073 if (pContext->attrib.enableStack[i].clip)
2074 {
2075 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.enableStack[i].clip,
2076 pContext->limits.maxClipPlanes*sizeof(GLboolean));
2077 AssertRCReturn(rc, rc);
2078 }
2079
2080 if (pContext->attrib.enableStack[i].light)
2081 {
2082 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.enableStack[i].light,
2083 pContext->limits.maxLights*sizeof(GLboolean));
2084 AssertRCReturn(rc, rc);
2085 }
2086
2087 if (pContext->attrib.lightingStack[i].light)
2088 {
2089 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.lightingStack[i].light,
2090 pContext->limits.maxLights*sizeof(CRLight));
2091 AssertRCReturn(rc, rc);
2092 }
2093
2094 for (k=0; k<pContext->limits.maxTextureUnits; ++k)
2095 {
2096 rc = crStateLoadTexUnitCurrentTexturePtrs(&pContext->attrib.textureStack[i].unit[k], pContext, pSSM);
2097 AssertRCReturn(rc, rc);
2098 }
2099
2100 if (pContext->attrib.transformStack[i].clip)
2101 {
2102 rc = crStateAllocAndSSMR3GetMem(pSSM, (void*)&pContext->attrib.transformStack[i].clip,
2103 pContext->limits.maxClipPlanes*sizeof(GLboolean));
2104 AssertRCReturn(rc, rc);
2105 }
2106
2107 if (pContext->attrib.transformStack[i].clipPlane)
2108 {
2109 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.transformStack[i].clipPlane,
2110 pContext->limits.maxClipPlanes*sizeof(GLvectord));
2111 AssertRCReturn(rc, rc);
2112 }
2113 rc = crSateLoadEvalCoeffs1D(pContext->attrib.evalStack[i].eval1D, GL_TRUE, pSSM);
2114 AssertRCReturn(rc, rc);
2115 rc = crSateLoadEvalCoeffs2D(pContext->attrib.evalStack[i].eval2D, GL_TRUE, pSSM);
2116 AssertRCReturn(rc, rc);
2117 }
2118
2119 /* Load evaluator coeffs */
2120 rc = crSateLoadEvalCoeffs1D(pContext->eval.eval1D, GL_FALSE, pSSM);
2121 AssertRCReturn(rc, rc);
2122 rc = crSateLoadEvalCoeffs2D(pContext->eval.eval2D, GL_FALSE, pSSM);
2123 AssertRCReturn(rc, rc);
2124
2125 /* Load buffer objects */
2126#ifdef CR_ARB_vertex_buffer_object
2127 rc = SSMR3GetU32(pSSM, &uiNumElems);
2128 AssertRCReturn(rc, rc);
2129 for (ui=0; ui<=uiNumElems; ++ui) /*ui<=uiNumElems to load nullBuffer in same loop*/
2130 {
2131 CRBufferObject *pBufferObj;
2132
2133 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
2134 AssertRCReturn(rc, rc);
2135
2136 /* default one should be already allocated */
2137 if (key==0)
2138 {
2139 pBufferObj = pContext->bufferobject.nullBuffer;
2140 if (!pBufferObj) return VERR_SSM_UNEXPECTED_DATA;
2141 }
2142 else
2143 {
2144 pBufferObj = (CRBufferObject *) crCalloc(sizeof(*pBufferObj));
2145 if (!pBufferObj) return VERR_NO_MEMORY;
2146 }
2147
2148 rc = crStateLoadBufferObject(pBufferObj, pSSM, u32Version);
2149 AssertRCReturn(rc, rc);
2150
2151 pBufferObj->hwid = 0;
2152
2153 if (pBufferObj->data)
2154 {
2155 CRASSERT(pBufferObj->size>0);
2156 pBufferObj->data = crAlloc(pBufferObj->size);
2157 rc = SSMR3GetMem(pSSM, pBufferObj->data, pBufferObj->size);
2158 AssertRCReturn(rc, rc);
2159 }
2160 else if (pBufferObj->id!=0 && pBufferObj->size>0)
2161 {
2162 rc = SSMR3GetMem(pSSM, &pBufferObj->data, sizeof(pBufferObj->data));
2163 AssertRCReturn(rc, rc);
2164
2165 if (pBufferObj->data)
2166 {
2167 pBufferObj->data = crAlloc(pBufferObj->size);
2168 rc = SSMR3GetMem(pSSM, pBufferObj->data, pBufferObj->size);
2169 AssertRCReturn(rc, rc);
2170 }
2171 }
2172
2173
2174 if (key!=0)
2175 crHashtableAdd(pContext->shared->buffersTable, key, pBufferObj);
2176 }
2177 /* Load pointers */
2178#define CRS_GET_BO(name) (((name)==0) ? (pContext->bufferobject.nullBuffer) : crHashtableSearch(pContext->shared->buffersTable, name))
2179 rc = SSMR3GetU32(pSSM, &ui);
2180 AssertRCReturn(rc, rc);
2181 pContext->bufferobject.arrayBuffer = CRS_GET_BO(ui);
2182 rc = SSMR3GetU32(pSSM, &ui);
2183 AssertRCReturn(rc, rc);
2184 pContext->bufferobject.elementsBuffer = CRS_GET_BO(ui);
2185#ifdef CR_ARB_pixel_buffer_object
2186 rc = SSMR3GetU32(pSSM, &ui);
2187 AssertRCReturn(rc, rc);
2188 pContext->bufferobject.packBuffer = CRS_GET_BO(ui);
2189 rc = SSMR3GetU32(pSSM, &ui);
2190 AssertRCReturn(rc, rc);
2191 pContext->bufferobject.unpackBuffer = CRS_GET_BO(ui);
2192#endif
2193#undef CRS_GET_BO
2194
2195 /* Load client pointers and array buffer bindings*/
2196 for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
2197 {
2198 rc = crStateLoadClientPointer(&pContext->client.array, i, pContext, pSSM);
2199 AssertRCReturn(rc, rc);
2200 }
2201 for (j=0; j<pContext->client.vertexArrayStackDepth; ++j)
2202 {
2203 CRVertexArrays *pArray = &pContext->client.vertexArrayStack[j];
2204 for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
2205 {
2206 rc = crStateLoadClientPointer(pArray, i, pContext, pSSM);
2207 AssertRCReturn(rc, rc);
2208 }
2209 }
2210
2211 pContext->shared->bVBOResyncNeeded = GL_TRUE;
2212#endif
2213
2214 /* Load pixel/vertex programs */
2215 rc = SSMR3GetU32(pSSM, &uiNumElems);
2216 AssertRCReturn(rc, rc);
2217 /* Load defaults programs */
2218 rc = crStateLoadProgram(&pContext->program.defaultVertexProgram, pSSM);
2219 AssertRCReturn(rc, rc);
2220 rc = crStateLoadProgram(&pContext->program.defaultFragmentProgram, pSSM);
2221 AssertRCReturn(rc, rc);
2222 /* Load all the rest */
2223 for (ui=0; ui<uiNumElems; ++ui)
2224 {
2225 CRProgram *pProgram = NULL;
2226 rc = crStateLoadProgram(&pProgram, pSSM);
2227 AssertRCReturn(rc, rc);
2228 crHashtableAdd(pContext->program.programHash, pProgram->id, pProgram);
2229 //DIRTY(pProgram->dirtyProgram, pContext->neg_bitid);
2230
2231 }
2232 /* Load Pointers */
2233 rc = SSMR3GetU32(pSSM, &ui);
2234 AssertRCReturn(rc, rc);
2235 pContext->program.currentVertexProgram = ui==0 ? pContext->program.defaultVertexProgram
2236 : crHashtableSearch(pContext->program.programHash, ui);
2237 rc = SSMR3GetU32(pSSM, &ui);
2238 AssertRCReturn(rc, rc);
2239 pContext->program.currentFragmentProgram = ui==0 ? pContext->program.defaultFragmentProgram
2240 : crHashtableSearch(pContext->program.programHash, ui);
2241
2242 /* Mark programs for resending to GPU */
2243 pContext->program.bResyncNeeded = GL_TRUE;
2244
2245#ifdef CR_EXT_framebuffer_object
2246 /* Load FBOs */
2247 if (bLoadShared)
2248 {
2249 rc = SSMR3GetU32(pSSM, &uiNumElems);
2250 AssertRCReturn(rc, rc);
2251 for (ui=0; ui<uiNumElems; ++ui)
2252 {
2253 CRFramebufferObject *pFBO;
2254 pFBO = crAlloc(sizeof(*pFBO));
2255 if (!pFBO) return VERR_NO_MEMORY;
2256
2257 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
2258 AssertRCReturn(rc, rc);
2259
2260 rc = crStateLoadFramebufferObject(pFBO, pSSM, u32Version);
2261 AssertRCReturn(rc, rc);
2262
2263 crHashtableAdd(pContext->shared->fbTable, key, pFBO);
2264 }
2265
2266 rc = SSMR3GetU32(pSSM, &uiNumElems);
2267 AssertRCReturn(rc, rc);
2268 for (ui=0; ui<uiNumElems; ++ui)
2269 {
2270 CRRenderbufferObject *pRBO;
2271 pRBO = crAlloc(sizeof(*pRBO));
2272 if (!pRBO) return VERR_NO_MEMORY;
2273
2274 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
2275 AssertRCReturn(rc, rc);
2276
2277 rc = crStateLoadRenderbufferObject(pRBO, pSSM, u32Version);
2278 AssertRCReturn(rc, rc);
2279
2280 crHashtableAdd(pContext->shared->rbTable, key, pRBO);
2281 }
2282 }
2283
2284 rc = SSMR3GetU32(pSSM, &ui);
2285 AssertRCReturn(rc, rc);
2286 pContext->framebufferobject.drawFB = ui==0 ? NULL
2287 : crHashtableSearch(pContext->shared->fbTable, ui);
2288
2289 rc = SSMR3GetU32(pSSM, &ui);
2290 AssertRCReturn(rc, rc);
2291 pContext->framebufferobject.readFB = ui==0 ? NULL
2292 : crHashtableSearch(pContext->shared->fbTable, ui);
2293
2294 rc = SSMR3GetU32(pSSM, &ui);
2295 AssertRCReturn(rc, rc);
2296 pContext->framebufferobject.renderbuffer = ui==0 ? NULL
2297 : crHashtableSearch(pContext->shared->rbTable, ui);
2298
2299 /* Mark FBOs/RBOs for resending to GPU */
2300 pContext->shared->bFBOResyncNeeded = GL_TRUE;
2301#endif
2302
2303#ifdef CR_OPENGL_VERSION_2_0
2304 /* Load GLSL related info */
2305 rc = SSMR3GetU32(pSSM, &uiNumElems);
2306 AssertRCReturn(rc, rc);
2307
2308 for (ui=0; ui<uiNumElems; ++ui)
2309 {
2310 CRGLSLShader *pShader = crStateLoadGLSLShader(pSSM);
2311 if (!pShader) return VERR_SSM_UNEXPECTED_DATA;
2312 crHashtableAdd(pContext->glsl.shaders, pShader->id, pShader);
2313 }
2314
2315 rc = SSMR3GetU32(pSSM, &uiNumElems);
2316 AssertRCReturn(rc, rc);
2317
2318 for (ui=0; ui<uiNumElems; ++ui)
2319 {
2320 CRGLSLProgram *pProgram;
2321 uint32_t numShaders;
2322
2323 pProgram = crAlloc(sizeof(*pProgram));
2324 if (!pProgram) return VERR_NO_MEMORY;
2325
2326 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
2327 AssertRCReturn(rc, rc);
2328
2329 rc = SSMR3GetMem(pSSM, pProgram, sizeof(*pProgram));
2330 AssertRCReturn(rc, rc);
2331
2332 crHashtableAdd(pContext->glsl.programs, key, pProgram);
2333
2334 pProgram->currentState.attachedShaders = crAllocHashtable();
2335
2336 rc = SSMR3GetU32(pSSM, &numShaders);
2337 AssertRCReturn(rc, rc);
2338
2339 for (k=0; k<numShaders; ++k)
2340 {
2341 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
2342 AssertRCReturn(rc, rc);
2343 crHashtableAdd(pProgram->currentState.attachedShaders, key, crHashtableSearch(pContext->glsl.shaders, key));
2344 }
2345
2346 if (pProgram->activeState.attachedShaders)
2347 {
2348 pProgram->activeState.attachedShaders = crAllocHashtable();
2349
2350 rc = SSMR3GetU32(pSSM, &numShaders);
2351 AssertRCReturn(rc, rc);
2352
2353 for (k=0; k<numShaders; ++k)
2354 {
2355 CRGLSLShader *pShader = crStateLoadGLSLShader(pSSM);
2356 if (!pShader) return VERR_SSM_UNEXPECTED_DATA;
2357 crHashtableAdd(pProgram->activeState.attachedShaders, pShader->id, pShader);
2358 }
2359 }
2360
2361 if (pProgram->currentState.cAttribs)
2362 pProgram->currentState.pAttribs = (CRGLSLAttrib*) crAlloc(pProgram->currentState.cAttribs*sizeof(CRGLSLAttrib));
2363 for (k=0; k<pProgram->currentState.cAttribs; ++k)
2364 {
2365 rc = SSMR3GetMem(pSSM, &pProgram->currentState.pAttribs[k].index, sizeof(pProgram->currentState.pAttribs[k].index));
2366 AssertRCReturn(rc, rc);
2367 pProgram->currentState.pAttribs[k].name = crStateLoadString(pSSM);
2368 }
2369
2370 if (pProgram->activeState.cAttribs)
2371 pProgram->activeState.pAttribs = (CRGLSLAttrib*) crAlloc(pProgram->activeState.cAttribs*sizeof(CRGLSLAttrib));
2372 for (k=0; k<pProgram->activeState.cAttribs; ++k)
2373 {
2374 rc = SSMR3GetMem(pSSM, &pProgram->activeState.pAttribs[k].index, sizeof(pProgram->activeState.pAttribs[k].index));
2375 AssertRCReturn(rc, rc);
2376 pProgram->activeState.pAttribs[k].name = crStateLoadString(pSSM);
2377 }
2378
2379 {
2380 int32_t cUniforms;
2381 rc = SSMR3GetS32(pSSM, &cUniforms);
2382 pProgram->cUniforms = cUniforms;
2383 AssertRCReturn(rc, rc);
2384 }
2385
2386 if (pProgram->cUniforms)
2387 {
2388 pProgram->pUniforms = crAlloc(pProgram->cUniforms*sizeof(CRGLSLUniform));
2389 if (!pProgram->pUniforms) return VERR_NO_MEMORY;
2390
2391 for (k=0; k<pProgram->cUniforms; ++k)
2392 {
2393 size_t itemsize, datasize;
2394
2395 rc = SSMR3GetMem(pSSM, &pProgram->pUniforms[k].type, sizeof(GLenum));
2396 AssertRCReturn(rc, rc);
2397 pProgram->pUniforms[k].name = crStateLoadString(pSSM);
2398
2399 if (crStateIsIntUniform(pProgram->pUniforms[k].type))
2400 {
2401 itemsize = sizeof(GLint);
2402 } else itemsize = sizeof(GLfloat);
2403
2404 datasize = crStateGetUniformSize(pProgram->pUniforms[k].type)*itemsize;
2405 pProgram->pUniforms[k].data = crAlloc(datasize);
2406 if (!pProgram->pUniforms[k].data) return VERR_NO_MEMORY;
2407
2408 rc = SSMR3GetMem(pSSM, pProgram->pUniforms[k].data, datasize);
2409 AssertRCReturn(rc, rc);
2410 }
2411 }
2412 }
2413
2414 rc = SSMR3GetU32(pSSM, &ui);
2415 AssertRCReturn(rc, rc);
2416 pContext->glsl.activeProgram = ui==0 ? NULL
2417 : crHashtableSearch(pContext->glsl.programs, ui);
2418
2419 /*Mark for resending to GPU*/
2420 pContext->glsl.bResyncNeeded = GL_TRUE;
2421#endif
2422
2423
2424 /*Restore front/back buffer images*/
2425 if (pContext->buffer.storedWidth && pContext->buffer.storedHeight)
2426 {
2427 CRBufferState *pBuf = &pContext->buffer;
2428 GLint cbData;
2429 void *pData;
2430
2431 cbData = crPixelSize(GL_RGBA, GL_UNSIGNED_BYTE) * pBuf->storedWidth * pBuf->storedHeight;
2432
2433 pData = crAlloc(cbData);
2434 if (!pData)
2435 {
2436 pBuf->pFrontImg = NULL;
2437 pBuf->pBackImg = NULL;
2438 return VERR_NO_MEMORY;
2439 }
2440
2441 rc = SSMR3GetMem(pSSM, pData, cbData);
2442 AssertRCReturn(rc, rc);
2443
2444 pBuf->pFrontImg = pData;
2445
2446 pData = crAlloc(cbData);
2447 if (!pData)
2448 {
2449 pBuf->pBackImg = NULL;
2450 return VERR_NO_MEMORY;
2451 }
2452
2453 rc = SSMR3GetMem(pSSM, pData, cbData);
2454 AssertRCReturn(rc, rc);
2455
2456 pBuf->pBackImg = pData;
2457 }
2458
2459
2460 /*Mark all as dirty to make sure we'd restore correct context state*/
2461 {
2462 CRStateBits *pBits = GetCurrentBits();
2463
2464 FILLDIRTY(pBits->attrib.dirty);
2465
2466 FILLDIRTY(pBits->buffer.dirty);
2467 FILLDIRTY(pBits->buffer.enable);
2468 FILLDIRTY(pBits->buffer.alphaFunc);
2469 FILLDIRTY(pBits->buffer.depthFunc);
2470 FILLDIRTY(pBits->buffer.blendFunc);
2471 FILLDIRTY(pBits->buffer.logicOp);
2472 FILLDIRTY(pBits->buffer.indexLogicOp);
2473 FILLDIRTY(pBits->buffer.drawBuffer);
2474 FILLDIRTY(pBits->buffer.readBuffer);
2475 FILLDIRTY(pBits->buffer.indexMask);
2476 FILLDIRTY(pBits->buffer.colorWriteMask);
2477 FILLDIRTY(pBits->buffer.clearColor);
2478 FILLDIRTY(pBits->buffer.clearIndex);
2479 FILLDIRTY(pBits->buffer.clearDepth);
2480 FILLDIRTY(pBits->buffer.clearAccum);
2481 FILLDIRTY(pBits->buffer.depthMask);
2482#ifdef CR_EXT_blend_color
2483 FILLDIRTY(pBits->buffer.blendColor);
2484#endif
2485#if defined(CR_EXT_blend_minmax) || defined(CR_EXT_blend_subtract) || defined(CR_EXT_blend_logic_op)
2486 FILLDIRTY(pBits->buffer.blendEquation);
2487#endif
2488#if defined(CR_EXT_blend_func_separate)
2489 FILLDIRTY(pBits->buffer.blendFuncSeparate);
2490#endif
2491
2492#ifdef CR_ARB_vertex_buffer_object
2493 FILLDIRTY(pBits->bufferobject.dirty);
2494 FILLDIRTY(pBits->bufferobject.arrayBinding);
2495 FILLDIRTY(pBits->bufferobject.elementsBinding);
2496# ifdef CR_ARB_pixel_buffer_object
2497 FILLDIRTY(pBits->bufferobject.packBinding);
2498 FILLDIRTY(pBits->bufferobject.unpackBinding);
2499# endif
2500#endif
2501
2502 FILLDIRTY(pBits->client.dirty);
2503 FILLDIRTY(pBits->client.pack);
2504 FILLDIRTY(pBits->client.unpack);
2505 FILLDIRTY(pBits->client.enableClientState);
2506 FILLDIRTY(pBits->client.clientPointer);
2507 FILLDIRTY(pBits->client.v);
2508 FILLDIRTY(pBits->client.n);
2509 FILLDIRTY(pBits->client.c);
2510 FILLDIRTY(pBits->client.i);
2511 FILLDIRTY(pBits->client.e);
2512 FILLDIRTY(pBits->client.s);
2513 FILLDIRTY(pBits->client.f);
2514 for (i=0; i<CR_MAX_TEXTURE_UNITS; i++)
2515 {
2516 FILLDIRTY(pBits->client.t[i]);
2517 }
2518#ifdef CR_NV_vertex_program
2519 for (i=0; i<CR_MAX_VERTEX_ATTRIBS; i++)
2520 {
2521 FILLDIRTY(pBits->client.a[i]);
2522 }
2523#endif
2524
2525 FILLDIRTY(pBits->current.dirty);
2526 for (i=0; i<CR_MAX_VERTEX_ATTRIBS; i++)
2527 {
2528 FILLDIRTY(pBits->current.vertexAttrib[i]);
2529 }
2530 FILLDIRTY(pBits->current.edgeFlag);
2531 FILLDIRTY(pBits->current.colorIndex);
2532 FILLDIRTY(pBits->current.rasterPos);
2533
2534
2535 FILLDIRTY(pBits->eval.dirty);
2536 for (i=0; i<GLEVAL_TOT; i++)
2537 {
2538 FILLDIRTY(pBits->eval.eval1D[i]);
2539 FILLDIRTY(pBits->eval.eval2D[i]);
2540 FILLDIRTY(pBits->eval.enable1D[i]);
2541 FILLDIRTY(pBits->eval.enable2D[i]);
2542 }
2543 FILLDIRTY(pBits->eval.enable);
2544 FILLDIRTY(pBits->eval.grid1D);
2545 FILLDIRTY(pBits->eval.grid2D);
2546#ifdef CR_NV_vertex_program
2547 /*@todo Those seems to be unused?
2548 FILLDIRTY(pBits->eval.enableAttrib1D);
2549 FILLDIRTY(pBits->eval.enableAttrib2D);
2550 */
2551#endif
2552
2553 FILLDIRTY(pBits->feedback.dirty);
2554 FILLDIRTY(pBits->selection.dirty);
2555
2556 FILLDIRTY(pBits->fog.dirty);
2557 FILLDIRTY(pBits->fog.color);
2558 FILLDIRTY(pBits->fog.index);
2559 FILLDIRTY(pBits->fog.density);
2560 FILLDIRTY(pBits->fog.start);
2561 FILLDIRTY(pBits->fog.end);
2562 FILLDIRTY(pBits->fog.mode);
2563 FILLDIRTY(pBits->fog.enable);
2564#ifdef CR_NV_fog_distance
2565 FILLDIRTY(pBits->fog.fogDistanceMode);
2566#endif
2567#ifdef CR_EXT_fog_coord
2568 FILLDIRTY(pBits->fog.fogCoordinateSource);
2569#endif
2570
2571 FILLDIRTY(pBits->hint.dirty);
2572 FILLDIRTY(pBits->hint.perspectiveCorrection);
2573 FILLDIRTY(pBits->hint.pointSmooth);
2574 FILLDIRTY(pBits->hint.lineSmooth);
2575 FILLDIRTY(pBits->hint.polygonSmooth);
2576 FILLDIRTY(pBits->hint.fog);
2577#ifdef CR_EXT_clip_volume_hint
2578 FILLDIRTY(pBits->hint.clipVolumeClipping);
2579
2580#endif
2581#ifdef CR_ARB_texture_compression
2582 FILLDIRTY(pBits->hint.textureCompression);
2583#endif
2584#ifdef CR_SGIS_generate_mipmap
2585 FILLDIRTY(pBits->hint.generateMipmap);
2586#endif
2587
2588 FILLDIRTY(pBits->lighting.dirty);
2589 FILLDIRTY(pBits->lighting.shadeModel);
2590 FILLDIRTY(pBits->lighting.colorMaterial);
2591 FILLDIRTY(pBits->lighting.lightModel);
2592 FILLDIRTY(pBits->lighting.material);
2593 FILLDIRTY(pBits->lighting.enable);
2594 for (i=0; i<CR_MAX_LIGHTS; ++i)
2595 {
2596 FILLDIRTY(pBits->lighting.light[i].dirty);
2597 FILLDIRTY(pBits->lighting.light[i].enable);
2598 FILLDIRTY(pBits->lighting.light[i].ambient);
2599 FILLDIRTY(pBits->lighting.light[i].diffuse);
2600 FILLDIRTY(pBits->lighting.light[i].specular);
2601 FILLDIRTY(pBits->lighting.light[i].position);
2602 FILLDIRTY(pBits->lighting.light[i].attenuation);
2603 FILLDIRTY(pBits->lighting.light[i].spot);
2604 }
2605
2606 FILLDIRTY(pBits->line.dirty);
2607 FILLDIRTY(pBits->line.enable);
2608 FILLDIRTY(pBits->line.width);
2609 FILLDIRTY(pBits->line.stipple);
2610
2611 FILLDIRTY(pBits->lists.dirty);
2612 FILLDIRTY(pBits->lists.base);
2613
2614 FILLDIRTY(pBits->multisample.dirty);
2615 FILLDIRTY(pBits->multisample.enable);
2616 FILLDIRTY(pBits->multisample.sampleAlphaToCoverage);
2617 FILLDIRTY(pBits->multisample.sampleAlphaToOne);
2618 FILLDIRTY(pBits->multisample.sampleCoverage);
2619 FILLDIRTY(pBits->multisample.sampleCoverageValue);
2620
2621#if CR_ARB_occlusion_query
2622 FILLDIRTY(pBits->occlusion.dirty);
2623#endif
2624
2625 FILLDIRTY(pBits->pixel.dirty);
2626 FILLDIRTY(pBits->pixel.transfer);
2627 FILLDIRTY(pBits->pixel.zoom);
2628 FILLDIRTY(pBits->pixel.maps);
2629
2630 FILLDIRTY(pBits->point.dirty);
2631 FILLDIRTY(pBits->point.enableSmooth);
2632 FILLDIRTY(pBits->point.size);
2633#ifdef CR_ARB_point_parameters
2634 FILLDIRTY(pBits->point.minSize);
2635 FILLDIRTY(pBits->point.maxSize);
2636 FILLDIRTY(pBits->point.fadeThresholdSize);
2637 FILLDIRTY(pBits->point.distanceAttenuation);
2638#endif
2639#ifdef CR_ARB_point_sprite
2640 FILLDIRTY(pBits->point.enableSprite);
2641 for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
2642 {
2643 FILLDIRTY(pBits->point.coordReplacement[i]);
2644 }
2645#endif
2646
2647 FILLDIRTY(pBits->polygon.dirty);
2648 FILLDIRTY(pBits->polygon.enable);
2649 FILLDIRTY(pBits->polygon.offset);
2650 FILLDIRTY(pBits->polygon.mode);
2651 FILLDIRTY(pBits->polygon.stipple);
2652
2653 FILLDIRTY(pBits->program.dirty);
2654 FILLDIRTY(pBits->program.vpEnable);
2655 FILLDIRTY(pBits->program.fpEnable);
2656 FILLDIRTY(pBits->program.vpBinding);
2657 FILLDIRTY(pBits->program.fpBinding);
2658 for (i=0; i<CR_MAX_VERTEX_ATTRIBS; ++i)
2659 {
2660 FILLDIRTY(pBits->program.vertexAttribArrayEnable[i]);
2661 FILLDIRTY(pBits->program.map1AttribArrayEnable[i]);
2662 FILLDIRTY(pBits->program.map2AttribArrayEnable[i]);
2663 }
2664 for (i=0; i<CR_MAX_VERTEX_PROGRAM_ENV_PARAMS; ++i)
2665 {
2666 FILLDIRTY(pBits->program.vertexEnvParameter[i]);
2667 }
2668 for (i=0; i<CR_MAX_FRAGMENT_PROGRAM_ENV_PARAMS; ++i)
2669 {
2670 FILLDIRTY(pBits->program.fragmentEnvParameter[i]);
2671 }
2672 FILLDIRTY(pBits->program.vertexEnvParameters);
2673 FILLDIRTY(pBits->program.fragmentEnvParameters);
2674 for (i=0; i<CR_MAX_VERTEX_PROGRAM_ENV_PARAMS/4; ++i)
2675 {
2676 FILLDIRTY(pBits->program.trackMatrix[i]);
2677 }
2678
2679 FILLDIRTY(pBits->regcombiner.dirty);
2680 FILLDIRTY(pBits->regcombiner.enable);
2681 FILLDIRTY(pBits->regcombiner.regCombinerVars);
2682 FILLDIRTY(pBits->regcombiner.regCombinerColor0);
2683 FILLDIRTY(pBits->regcombiner.regCombinerColor1);
2684 for (i=0; i<CR_MAX_GENERAL_COMBINERS; ++i)
2685 {
2686 FILLDIRTY(pBits->regcombiner.regCombinerStageColor0[i]);
2687 FILLDIRTY(pBits->regcombiner.regCombinerStageColor1[i]);
2688 FILLDIRTY(pBits->regcombiner.regCombinerInput[i]);
2689 FILLDIRTY(pBits->regcombiner.regCombinerOutput[i]);
2690 }
2691 FILLDIRTY(pBits->regcombiner.regCombinerFinalInput);
2692
2693 FILLDIRTY(pBits->stencil.dirty);
2694 FILLDIRTY(pBits->stencil.enable);
2695 FILLDIRTY(pBits->stencil.func);
2696 FILLDIRTY(pBits->stencil.op);
2697 FILLDIRTY(pBits->stencil.clearValue);
2698 FILLDIRTY(pBits->stencil.writeMask);
2699
2700 FILLDIRTY(pBits->texture.dirty);
2701 for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
2702 {
2703 FILLDIRTY(pBits->texture.enable[i]);
2704 FILLDIRTY(pBits->texture.current[i]);
2705 FILLDIRTY(pBits->texture.objGen[i]);
2706 FILLDIRTY(pBits->texture.eyeGen[i]);
2707 FILLDIRTY(pBits->texture.genMode[i]);
2708 FILLDIRTY(pBits->texture.envBit[i]);
2709 }
2710
2711 FILLDIRTY(pBits->transform.dirty);
2712 FILLDIRTY(pBits->transform.matrixMode);
2713 FILLDIRTY(pBits->transform.modelviewMatrix);
2714 FILLDIRTY(pBits->transform.projectionMatrix);
2715 FILLDIRTY(pBits->transform.colorMatrix);
2716 FILLDIRTY(pBits->transform.textureMatrix);
2717 FILLDIRTY(pBits->transform.programMatrix);
2718 FILLDIRTY(pBits->transform.clipPlane);
2719 FILLDIRTY(pBits->transform.enable);
2720 FILLDIRTY(pBits->transform.base);
2721
2722 FILLDIRTY(pBits->viewport.dirty);
2723 FILLDIRTY(pBits->viewport.v_dims);
2724 FILLDIRTY(pBits->viewport.s_dims);
2725 FILLDIRTY(pBits->viewport.enable);
2726 FILLDIRTY(pBits->viewport.depth);
2727 }
2728
2729 return VINF_SUCCESS;
2730}
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