VirtualBox

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

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

crOpenGL: additional saved state fix

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