VirtualBox

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

Last change on this file since 41205 was 41132, checked in by vboxsync, 13 years ago

state_snapshot.c: Use SSMR3Skip instead of SMMR3GetMem to skip a few bytes ahead in the stream. GCC v4.5.2 cannot cope with the associated compile time assertions, commented them out.

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

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