VirtualBox

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

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

crOpenGL: backwards compatibility for 3D saved state v 28

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