VirtualBox

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

Last change on this file since 23123 was 23123, checked in by vboxsync, 16 years ago

crOpenGL: snapshots support for VBOs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 45.2 KB
Line 
1/* $Id: state_snapshot.c 23123 2009-09-18 11:21:22Z vboxsync $ */
2
3/** @file
4 * VBox Context state saving/loading used by VM snapshot
5 */
6
7/*
8 * Copyright (C) 2008 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22
23#include "state.h"
24#include "state/cr_statetypes.h"
25#include "state/cr_texture.h"
26#include "cr_mem.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
53/*@todo move with the one from state_texture.c to some header*/
54#define MAX_MIPMAP_LEVELS 20
55
56static int32_t crStateAllocAndSSMR3GetMem(PSSMHANDLE pSSM, void **pBuffer, size_t cbBuffer)
57{
58 CRASSERT(pSSM && pBuffer && cbBuffer>0);
59
60 *pBuffer = crAlloc(cbBuffer);
61 if (!*pBuffer)
62 return VERR_NO_MEMORY;
63
64 return SSMR3GetMem(pSSM, *pBuffer, cbBuffer);
65}
66
67static int32_t crStateSaveTextureObjData(CRTextureObj *pTexture, PSSMHANDLE pSSM)
68{
69 int32_t rc, face, i;
70
71 CRASSERT(pTexture && pSSM);
72
73 for (face = 0; face < 6; face++) {
74 CRASSERT(pTexture->level[face]);
75
76 /*@todo, check if safe to go till MAX_MIPMAP_LEVELS intead of TextureState->maxLevel*/
77 for (i = 0; i < MAX_MIPMAP_LEVELS; i++) {
78 CRTextureLevel *ptl = &(pTexture->level[face][i]);
79 rc = SSMR3PutMem(pSSM, ptl, sizeof(*ptl));
80 AssertRCReturn(rc, rc);
81 if (ptl->img)
82 {
83 CRASSERT(ptl->bytes);
84 rc = SSMR3PutMem(pSSM, ptl->img, ptl->bytes);
85 AssertRCReturn(rc, rc);
86 }
87#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
88 /* Note, this is not a bug.
89 * Even with CR_STATE_NO_TEXTURE_IMAGE_STORE defined, it's possible that ptl->img!=NULL.
90 * For ex. we're saving snapshot right after it was loaded
91 * and some context hasn't been used by the guest application yet
92 * (pContext->texture.bResyncNeeded==GL_TRUE).
93 */
94 else if (ptl->bytes)
95 {
96 char *pImg;
97
98 pImg = crAlloc(ptl->bytes);
99 if (!pImg) return VERR_NO_MEMORY;
100
101 diff_api.BindTexture(pTexture->target, pTexture->name);
102 diff_api.GetTexImage(pTexture->target, i, ptl->format, ptl->type, pImg);
103
104 rc = SSMR3PutMem(pSSM, pImg, ptl->bytes);
105 crFree(pImg);
106 AssertRCReturn(rc, rc);
107 }
108#endif
109 }
110 }
111
112 return VINF_SUCCESS;
113}
114
115static int32_t crStateLoadTextureObjData(CRTextureObj *pTexture, PSSMHANDLE pSSM)
116{
117 int32_t rc, face, i;
118
119 CRASSERT(pTexture && pSSM);
120
121 for (face = 0; face < 6; face++) {
122 CRASSERT(pTexture->level[face]);
123
124 for (i = 0; i < MAX_MIPMAP_LEVELS; i++) {
125 CRTextureLevel *ptl = &(pTexture->level[face][i]);
126 CRASSERT(!ptl->img);
127
128 rc = SSMR3GetMem(pSSM, ptl, sizeof(*ptl));
129 AssertRCReturn(rc, rc);
130 if (ptl->img)
131 {
132 CRASSERT(ptl->bytes);
133
134 ptl->img = crAlloc(ptl->bytes);
135 if (!ptl->img) return VERR_NO_MEMORY;
136
137 rc = SSMR3GetMem(pSSM, ptl->img, ptl->bytes);
138 AssertRCReturn(rc, rc);
139 }
140#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
141 /* Same story as in crStateSaveTextureObjData */
142 else if (ptl->bytes)
143 {
144 ptl->img = crAlloc(ptl->bytes);
145 if (!ptl->img) return VERR_NO_MEMORY;
146
147 rc = SSMR3GetMem(pSSM, ptl->img, ptl->bytes);
148 AssertRCReturn(rc, rc);
149 }
150#endif
151 crStateTextureInitTextureFormat(ptl, ptl->internalFormat);
152
153 //FILLDIRTY(ptl->dirty);
154 }
155 }
156
157 return VINF_SUCCESS;
158}
159
160static void crStateSaveSharedTextureCB(unsigned long key, void *data1, void *data2)
161{
162 CRTextureObj *pTexture = (CRTextureObj *) data1;
163 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
164 int32_t rc;
165
166 CRASSERT(pTexture && pSSM);
167
168 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
169 CRASSERT(rc == VINF_SUCCESS);
170 rc = SSMR3PutMem(pSSM, pTexture, sizeof(*pTexture));
171 CRASSERT(rc == VINF_SUCCESS);
172 rc = crStateSaveTextureObjData(pTexture, pSSM);
173 CRASSERT(rc == VINF_SUCCESS);
174}
175
176static int32_t crStateSaveMatrixStack(CRMatrixStack *pStack, PSSMHANDLE pSSM)
177{
178 return SSMR3PutMem(pSSM, pStack->stack, sizeof(CRmatrix) * pStack->maxDepth);
179}
180
181static int32_t crStateLoadMatrixStack(CRMatrixStack *pStack, PSSMHANDLE pSSM)
182{
183 int32_t rc;
184
185 CRASSERT(pStack && pSSM);
186
187 rc = SSMR3GetMem(pSSM, pStack->stack, sizeof(CRmatrix) * pStack->maxDepth);
188 /* fixup stack top pointer */
189 pStack->top = &pStack->stack[pStack->depth];
190 return rc;
191}
192
193static int32_t crStateSaveTextureObjPtr(CRTextureObj *pTexture, PSSMHANDLE pSSM)
194{
195 /* Current texture pointer can't be NULL for real texture unit states,
196 * but it could be NULL for unused attribute stack depths.
197 */
198 if (pTexture)
199 return SSMR3PutU32(pSSM, pTexture->name);
200 else
201 return VINF_SUCCESS;
202}
203
204static int32_t crStateLoadTextureObjPtr(CRTextureObj **pTexture, CRContext *pContext, GLenum target, PSSMHANDLE pSSM)
205{
206 uint32_t texName;
207 int32_t rc;
208
209 /* We're loading attrib stack with unused state */
210 if (!*pTexture)
211 return VINF_SUCCESS;
212
213 rc = SSMR3GetU32(pSSM, &texName);
214 AssertRCReturn(rc, rc);
215
216 if (texName)
217 {
218 *pTexture = (CRTextureObj *) crHashtableSearch(pContext->shared->textureTable, texName);
219 }
220 else
221 {
222 switch (target)
223 {
224 case GL_TEXTURE_1D:
225 *pTexture = &(pContext->texture.base1D);
226 break;
227 case GL_TEXTURE_2D:
228 *pTexture = &(pContext->texture.base2D);
229 break;
230#ifdef CR_OPENGL_VERSION_1_2
231 case GL_TEXTURE_3D:
232 *pTexture = &(pContext->texture.base3D);
233 break;
234#endif
235#ifdef CR_ARB_texture_cube_map
236 case GL_TEXTURE_CUBE_MAP_ARB:
237 *pTexture = &(pContext->texture.baseCubeMap);
238 break;
239#endif
240#ifdef CR_NV_texture_rectangle
241 case GL_TEXTURE_RECTANGLE_NV:
242 *pTexture = &(pContext->texture.baseRect);
243 break;
244#endif
245 default:
246 crError("LoadTextureObjPtr: Unknown texture target %d", target);
247 }
248 }
249
250 return rc;
251}
252
253static int32_t crStateSaveTexUnitCurrentTexturePtrs(CRTextureUnit *pTexUnit, PSSMHANDLE pSSM)
254{
255 int32_t rc;
256
257 rc = crStateSaveTextureObjPtr(pTexUnit->currentTexture1D, pSSM);
258 AssertRCReturn(rc, rc);
259 rc = crStateSaveTextureObjPtr(pTexUnit->currentTexture2D, pSSM);
260 AssertRCReturn(rc, rc);
261 rc = crStateSaveTextureObjPtr(pTexUnit->currentTexture3D, pSSM);
262 AssertRCReturn(rc, rc);
263#ifdef CR_ARB_texture_cube_map
264 rc = crStateSaveTextureObjPtr(pTexUnit->currentTextureCubeMap, pSSM);
265 AssertRCReturn(rc, rc);
266#endif
267#ifdef CR_NV_texture_rectangle
268 rc = crStateSaveTextureObjPtr(pTexUnit->currentTextureRect, pSSM);
269 AssertRCReturn(rc, rc);
270#endif
271
272 return rc;
273}
274
275static int32_t crStateLoadTexUnitCurrentTexturePtrs(CRTextureUnit *pTexUnit, CRContext *pContext, PSSMHANDLE pSSM)
276{
277 int32_t rc;
278
279 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTexture1D, pContext, GL_TEXTURE_1D, pSSM);
280 AssertRCReturn(rc, rc);
281 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTexture2D, pContext, GL_TEXTURE_1D, pSSM);
282 AssertRCReturn(rc, rc);
283 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTexture3D, pContext, GL_TEXTURE_2D, pSSM);
284 AssertRCReturn(rc, rc);
285#ifdef CR_ARB_texture_cube_map
286 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTextureCubeMap, pContext, GL_TEXTURE_CUBE_MAP_ARB, pSSM);
287 AssertRCReturn(rc, rc);
288#endif
289#ifdef CR_NV_texture_rectangle
290 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTextureRect, pContext, GL_TEXTURE_RECTANGLE_NV, pSSM);
291 AssertRCReturn(rc, rc);
292#endif
293
294 return rc;
295}
296
297static int32_t crSateSaveEvalCoeffs1D(CREvaluator1D *pEval, PSSMHANDLE pSSM)
298{
299 int32_t rc, i;
300
301 for (i=0; i<GLEVAL_TOT; ++i)
302 {
303 if (pEval[i].coeff)
304 {
305 rc = SSMR3PutMem(pSSM, pEval[i].coeff, pEval[i].order * gleval_sizes[i] * sizeof(GLfloat));
306 AssertRCReturn(rc, rc);
307 }
308 }
309
310 return VINF_SUCCESS;
311}
312
313static int32_t crSateSaveEvalCoeffs2D(CREvaluator2D *pEval, PSSMHANDLE pSSM)
314{
315 int32_t rc, i;
316
317 for (i=0; i<GLEVAL_TOT; ++i)
318 {
319 if (pEval[i].coeff)
320 {
321 rc = SSMR3PutMem(pSSM, pEval[i].coeff, pEval[i].uorder * pEval[i].vorder * gleval_sizes[i] * sizeof(GLfloat));
322 AssertRCReturn(rc, rc);
323 }
324 }
325
326 return VINF_SUCCESS;
327}
328
329static int32_t crSateLoadEvalCoeffs1D(CREvaluator1D *pEval, GLboolean bReallocMem, PSSMHANDLE pSSM)
330{
331 int32_t rc, i;
332 size_t size;
333
334 for (i=0; i<GLEVAL_TOT; ++i)
335 {
336 if (pEval[i].coeff)
337 {
338 size = pEval[i].order * gleval_sizes[i] * sizeof(GLfloat);
339 if (bReallocMem)
340 {
341 pEval[i].coeff = (GLfloat*) crAlloc(size);
342 if (!pEval[i].coeff) return VERR_NO_MEMORY;
343 }
344 rc = SSMR3GetMem(pSSM, pEval[i].coeff, size);
345 AssertRCReturn(rc, rc);
346 }
347 }
348
349 return VINF_SUCCESS;
350}
351
352static int32_t crSateLoadEvalCoeffs2D(CREvaluator2D *pEval, GLboolean bReallocMem, PSSMHANDLE pSSM)
353{
354 int32_t rc, i;
355 size_t size;
356
357 for (i=0; i<GLEVAL_TOT; ++i)
358 {
359 if (pEval[i].coeff)
360 {
361 size = pEval[i].uorder * pEval[i].vorder * gleval_sizes[i] * sizeof(GLfloat);
362 if (bReallocMem)
363 {
364 pEval[i].coeff = (GLfloat*) crAlloc(size);
365 if (!pEval[i].coeff) return VERR_NO_MEMORY;
366 }
367 rc = SSMR3GetMem(pSSM, pEval[i].coeff, size);
368 AssertRCReturn(rc, rc);
369 }
370 }
371
372 return VINF_SUCCESS;
373}
374
375static void crStateCopyEvalPtrs1D(CREvaluator1D *pDst, CREvaluator1D *pSrc)
376{
377 int32_t i;
378
379 for (i=0; i<GLEVAL_TOT; ++i)
380 pDst[i].coeff = pSrc[i].coeff;
381
382 /*
383 pDst[GL_MAP1_VERTEX_3-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_VERTEX_3-GL_MAP1_COLOR_4].coeff;
384 pDst[GL_MAP1_VERTEX_4-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_VERTEX_4-GL_MAP1_COLOR_4].coeff;
385 pDst[GL_MAP1_INDEX-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_INDEX-GL_MAP1_COLOR_4].coeff;
386 pDst[GL_MAP1_COLOR_4-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_COLOR_4-GL_MAP1_COLOR_4].coeff;
387 pDst[GL_MAP1_NORMAL-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_NORMAL-GL_MAP1_COLOR_4].coeff;
388 pDst[GL_MAP1_TEXTURE_COORD_1-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_1-GL_MAP1_COLOR_4].coeff;
389 pDst[GL_MAP1_TEXTURE_COORD_2-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_2-GL_MAP1_COLOR_4].coeff;
390 pDst[GL_MAP1_TEXTURE_COORD_3-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_3-GL_MAP1_COLOR_4].coeff;
391 pDst[GL_MAP1_TEXTURE_COORD_4-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_4-GL_MAP1_COLOR_4].coeff;
392 */
393}
394
395static void crStateCopyEvalPtrs2D(CREvaluator2D *pDst, CREvaluator2D *pSrc)
396{
397 int32_t i;
398
399 for (i=0; i<GLEVAL_TOT; ++i)
400 pDst[i].coeff = pSrc[i].coeff;
401
402 /*
403 pDst[GL_MAP2_VERTEX_3-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_VERTEX_3-GL_MAP2_COLOR_4].coeff;
404 pDst[GL_MAP2_VERTEX_4-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_VERTEX_4-GL_MAP2_COLOR_4].coeff;
405 pDst[GL_MAP2_INDEX-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_INDEX-GL_MAP2_COLOR_4].coeff;
406 pDst[GL_MAP2_COLOR_4-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_COLOR_4-GL_MAP2_COLOR_4].coeff;
407 pDst[GL_MAP2_NORMAL-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_NORMAL-GL_MAP2_COLOR_4].coeff;
408 pDst[GL_MAP2_TEXTURE_COORD_1-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_1-GL_MAP2_COLOR_4].coeff;
409 pDst[GL_MAP2_TEXTURE_COORD_2-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_2-GL_MAP2_COLOR_4].coeff;
410 pDst[GL_MAP2_TEXTURE_COORD_3-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_3-GL_MAP2_COLOR_4].coeff;
411 pDst[GL_MAP2_TEXTURE_COORD_4-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_4-GL_MAP2_COLOR_4].coeff;
412 */
413}
414
415static void crStateSaveBufferObjectCB(unsigned long key, void *data1, void *data2)
416{
417 CRBufferObject *pBufferObj = (CRBufferObject *) data1;
418 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
419 int32_t rc;
420
421 CRASSERT(pBufferObj && pSSM);
422
423 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
424 CRASSERT(rc == VINF_SUCCESS);
425 rc = SSMR3PutMem(pSSM, pBufferObj, sizeof(*pBufferObj));
426 CRASSERT(rc == VINF_SUCCESS);
427
428 if (pBufferObj->data)
429 {
430 /*We could get here even though retainBufferData is false on host side, in case when we're taking snapshot
431 after state load and before this context was ever made current*/
432 CRASSERT(pBufferObj->size>0);
433 rc = SSMR3PutMem(pSSM, pBufferObj->data, pBufferObj->size);
434 CRASSERT(rc == VINF_SUCCESS);
435 }
436 else if (pBufferObj->name!=0 && pBufferObj->size>0)
437 {
438 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, pBufferObj->name);
439 pBufferObj->pointer = diff_api.MapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_ONLY_ARB);
440 rc = SSMR3PutMem(pSSM, &pBufferObj->pointer, sizeof(pBufferObj->pointer));
441 CRASSERT(rc == VINF_SUCCESS);
442 if (pBufferObj->pointer)
443 {
444 rc = SSMR3PutMem(pSSM, pBufferObj->pointer, pBufferObj->size);
445 CRASSERT(rc == VINF_SUCCESS);
446 }
447 diff_api.UnmapBufferARB(GL_ARRAY_BUFFER_ARB);
448 pBufferObj->pointer = NULL;
449 }
450}
451
452static void crStateSaveProgramCB(unsigned long key, void *data1, void *data2)
453{
454 CRProgram *pProgram = (CRProgram *) data1;
455 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
456 CRProgramSymbol *pSymbol;
457 int32_t rc;
458
459 CRASSERT(pProgram && pSSM);
460
461 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
462 CRASSERT(rc == VINF_SUCCESS);
463 rc = SSMR3PutMem(pSSM, pProgram, sizeof(*pProgram));
464 CRASSERT(rc == VINF_SUCCESS);
465 if (pProgram->string)
466 {
467 CRASSERT(pProgram->length);
468 rc = SSMR3PutMem(pSSM, pProgram->string, pProgram->length);
469 CRASSERT(rc == VINF_SUCCESS);
470 }
471
472 for (pSymbol = pProgram->symbolTable; pSymbol; pSymbol=pSymbol->next)
473 {
474 rc = SSMR3PutMem(pSSM, pSymbol, sizeof(*pSymbol));
475 CRASSERT(rc == VINF_SUCCESS);
476 if (pSymbol->name)
477 {
478 CRASSERT(pSymbol->cbName>0);
479 rc = SSMR3PutMem(pSSM, pSymbol->name, pSymbol->cbName);
480 CRASSERT(rc == VINF_SUCCESS);
481 }
482 }
483}
484
485static void crStateSaveFramebuffersCB(unsigned long key, void *data1, void *data2)
486{
487 CRFramebufferObject *pFBO = (CRFramebufferObject*) data1;
488 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
489 int32_t rc;
490
491 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
492 CRASSERT(rc == VINF_SUCCESS);
493
494 rc = SSMR3PutMem(pSSM, pFBO, sizeof(*pFBO));
495 CRASSERT(rc == VINF_SUCCESS);
496}
497
498static void crStateSaveRenderbuffersCB(unsigned long key, void *data1, void *data2)
499{
500 CRRenderbufferObject *pRBO = (CRRenderbufferObject*) data1;
501 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
502 int32_t rc;
503
504 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
505 CRASSERT(rc == VINF_SUCCESS);
506
507 rc = SSMR3PutMem(pSSM, pRBO, sizeof(*pRBO));
508 CRASSERT(rc == VINF_SUCCESS);
509}
510
511static int32_t crStateLoadProgram(CRProgram **ppProgram, PSSMHANDLE pSSM)
512{
513 CRProgramSymbol **ppSymbol;
514 int32_t rc;
515 unsigned long key;
516
517 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
518 AssertRCReturn(rc, rc);
519
520 /* we're loading default vertex or pixel program*/
521 if (*ppProgram)
522 {
523 if (key!=0) return VERR_SSM_UNEXPECTED_DATA;
524 }
525 else
526 {
527 *ppProgram = (CRProgram*) crAlloc(sizeof(CRProgram));
528 if (!ppProgram) return VERR_NO_MEMORY;
529 if (key==0) return VERR_SSM_UNEXPECTED_DATA;
530 }
531
532 rc = SSMR3GetMem(pSSM, *ppProgram, sizeof(**ppProgram));
533 AssertRCReturn(rc, rc);
534
535 if ((*ppProgram)->string)
536 {
537 CRASSERT((*ppProgram)->length);
538 (*ppProgram)->string = crAlloc((*ppProgram)->length);
539 if (!(*ppProgram)->string) return VERR_NO_MEMORY;
540 rc = SSMR3GetMem(pSSM, (void*) (*ppProgram)->string, (*ppProgram)->length);
541 AssertRCReturn(rc, rc);
542 }
543
544 for (ppSymbol = &(*ppProgram)->symbolTable; *ppSymbol; ppSymbol=&(*ppSymbol)->next)
545 {
546 *ppSymbol = crAlloc(sizeof(CRProgramSymbol));
547 if (!ppSymbol) return VERR_NO_MEMORY;
548
549 rc = SSMR3GetMem(pSSM, *ppSymbol, sizeof(**ppSymbol));
550 AssertRCReturn(rc, rc);
551
552 if ((*ppSymbol)->name)
553 {
554 CRASSERT((*ppSymbol)->cbName>0);
555 (*ppSymbol)->name = crAlloc((*ppSymbol)->cbName);
556 if (!(*ppSymbol)->name) return VERR_NO_MEMORY;
557
558 rc = SSMR3GetMem(pSSM, (void*) (*ppSymbol)->name, (*ppSymbol)->cbName);
559 AssertRCReturn(rc, rc);
560 }
561 }
562
563 return VINF_SUCCESS;
564}
565
566int32_t crStateSaveContext(CRContext *pContext, PSSMHANDLE pSSM)
567{
568 int32_t rc, i;
569 uint32_t ui32, j;
570
571 CRASSERT(pContext && pSSM);
572
573 rc = SSMR3PutMem(pSSM, pContext, sizeof(*pContext));
574 AssertRCReturn(rc, rc);
575
576 if (crHashtableNumElements(pContext->shared->dlistTable)>0)
577 crWarning("Saving state with %d display lists, unsupported", crHashtableNumElements(pContext->shared->dlistTable));
578
579 if (crHashtableNumElements(pContext->program.programHash)>0)
580 crDebug("Saving state with %d programs", crHashtableNumElements(pContext->program.programHash));
581
582 /* Save transform state */
583 rc = SSMR3PutMem(pSSM, pContext->transform.clipPlane, sizeof(GLvectord)*CR_MAX_CLIP_PLANES);
584 AssertRCReturn(rc, rc);
585 rc = SSMR3PutMem(pSSM, pContext->transform.clip, sizeof(GLboolean)*CR_MAX_CLIP_PLANES);
586 AssertRCReturn(rc, rc);
587 rc = crStateSaveMatrixStack(&pContext->transform.modelViewStack, pSSM);
588 AssertRCReturn(rc, rc);
589 rc = crStateSaveMatrixStack(&pContext->transform.projectionStack, pSSM);
590 AssertRCReturn(rc, rc);
591 rc = crStateSaveMatrixStack(&pContext->transform.colorStack, pSSM);
592 AssertRCReturn(rc, rc);
593 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
594 {
595 rc = crStateSaveMatrixStack(&pContext->transform.textureStack[i], pSSM);
596 AssertRCReturn(rc, rc);
597 }
598 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
599 {
600 rc = crStateSaveMatrixStack(&pContext->transform.programStack[i], pSSM);
601 AssertRCReturn(rc, rc);
602 }
603
604 /* Save textures */
605 rc = crStateSaveTextureObjData(&pContext->texture.base1D, pSSM);
606 AssertRCReturn(rc, rc);
607 rc = crStateSaveTextureObjData(&pContext->texture.base2D, pSSM);
608 AssertRCReturn(rc, rc);
609 rc = crStateSaveTextureObjData(&pContext->texture.base3D, pSSM);
610 AssertRCReturn(rc, rc);
611 rc = crStateSaveTextureObjData(&pContext->texture.proxy1D, pSSM);
612 AssertRCReturn(rc, rc);
613 rc = crStateSaveTextureObjData(&pContext->texture.proxy2D, pSSM);
614 AssertRCReturn(rc, rc);
615 rc = crStateSaveTextureObjData(&pContext->texture.proxy3D, pSSM);
616#ifdef CR_ARB_texture_cube_map
617 rc = crStateSaveTextureObjData(&pContext->texture.baseCubeMap, pSSM);
618 AssertRCReturn(rc, rc);
619 rc = crStateSaveTextureObjData(&pContext->texture.proxyCubeMap, pSSM);
620 AssertRCReturn(rc, rc);
621#endif
622#ifdef CR_NV_texture_rectangle
623 rc = crStateSaveTextureObjData(&pContext->texture.baseRect, pSSM);
624 AssertRCReturn(rc, rc);
625 rc = crStateSaveTextureObjData(&pContext->texture.proxyRect, pSSM);
626 AssertRCReturn(rc, rc);
627#endif
628
629 /* Save shared textures */
630 CRASSERT(pContext->shared && pContext->shared->textureTable);
631 ui32 = crHashtableNumElements(pContext->shared->textureTable);
632 rc = SSMR3PutU32(pSSM, ui32);
633 AssertRCReturn(rc, rc);
634 crHashtableWalk(pContext->shared->textureTable, crStateSaveSharedTextureCB, pSSM);
635
636#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
637 /* Restore previous texture bindings via diff_api */
638 if (ui32)
639 {
640 CRTextureUnit *pTexUnit;
641
642 pTexUnit = &pContext->texture.unit[pContext->texture.curTextureUnit];
643
644 diff_api.BindTexture(GL_TEXTURE_1D, pTexUnit->currentTexture1D->name);
645 diff_api.BindTexture(GL_TEXTURE_2D, pTexUnit->currentTexture2D->name);
646 diff_api.BindTexture(GL_TEXTURE_3D, pTexUnit->currentTexture3D->name);
647#ifdef CR_ARB_texture_cube_map
648 diff_api.BindTexture(GL_TEXTURE_CUBE_MAP_ARB, pTexUnit->currentTextureCubeMap->name);
649#endif
650#ifdef CR_NV_texture_rectangle
651 diff_api.BindTexture(GL_TEXTURE_RECTANGLE_NV, pTexUnit->currentTextureRect->name);
652#endif
653 }
654#endif
655
656 /* Save current texture pointers */
657 for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
658 {
659 rc = crStateSaveTexUnitCurrentTexturePtrs(&pContext->texture.unit[i], pSSM);
660 AssertRCReturn(rc, rc);
661 }
662
663 /* Save lights */
664 CRASSERT(pContext->lighting.light);
665 rc = SSMR3PutMem(pSSM, pContext->lighting.light, CR_MAX_LIGHTS * sizeof(*pContext->lighting.light));
666 AssertRCReturn(rc, rc);
667
668 /* Save attrib stack*/
669 /*@todo could go up to used stack depth here?*/
670 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
671 {
672 if (pContext->attrib.enableStack[i].clip)
673 {
674 rc = SSMR3PutMem(pSSM, pContext->attrib.enableStack[i].clip,
675 pContext->limits.maxClipPlanes*sizeof(GLboolean));
676 AssertRCReturn(rc, rc);
677 }
678
679 if (pContext->attrib.enableStack[i].light)
680 {
681 rc = SSMR3PutMem(pSSM, pContext->attrib.enableStack[i].light,
682 pContext->limits.maxLights*sizeof(GLboolean));
683 AssertRCReturn(rc, rc);
684 }
685
686 if (pContext->attrib.lightingStack[i].light)
687 {
688 rc = SSMR3PutMem(pSSM, pContext->attrib.lightingStack[i].light,
689 pContext->limits.maxLights*sizeof(CRLight));
690 AssertRCReturn(rc, rc);
691 }
692
693 for (j=0; j<pContext->limits.maxTextureUnits; ++j)
694 {
695 rc = crStateSaveTexUnitCurrentTexturePtrs(&pContext->attrib.textureStack[i].unit[j], pSSM);
696 AssertRCReturn(rc, rc);
697 }
698
699 if (pContext->attrib.transformStack[i].clip)
700 {
701 rc = SSMR3PutMem(pSSM, pContext->attrib.transformStack[i].clip,
702 pContext->limits.maxClipPlanes*sizeof(GLboolean));
703 AssertRCReturn(rc, rc);
704 }
705
706 if (pContext->attrib.transformStack[i].clipPlane)
707 {
708 rc = SSMR3PutMem(pSSM, pContext->attrib.transformStack[i].clipPlane,
709 pContext->limits.maxClipPlanes*sizeof(GLvectord));
710 AssertRCReturn(rc, rc);
711 }
712
713 rc = crSateSaveEvalCoeffs1D(pContext->attrib.evalStack[i].eval1D, pSSM);
714 AssertRCReturn(rc, rc);
715 rc = crSateSaveEvalCoeffs2D(pContext->attrib.evalStack[i].eval2D, pSSM);
716 AssertRCReturn(rc, rc);
717 }
718
719 /* Save evaluator coeffs */
720 rc = crSateSaveEvalCoeffs1D(pContext->eval.eval1D, pSSM);
721 AssertRCReturn(rc, rc);
722 rc = crSateSaveEvalCoeffs2D(pContext->eval.eval2D, pSSM);
723 AssertRCReturn(rc, rc);
724
725#ifdef CR_ARB_vertex_buffer_object
726 /* Save buffer objects */
727 ui32 = crHashtableNumElements(pContext->bufferobject.buffers);
728 rc = SSMR3PutU32(pSSM, ui32);
729 AssertRCReturn(rc, rc);
730 /* Save default one*/
731 crStateSaveBufferObjectCB(0, pContext->bufferobject.nullBuffer, pSSM);
732 /* Save all the rest */
733 crHashtableWalk(pContext->bufferobject.buffers, crStateSaveBufferObjectCB, pSSM);
734 /* Restore binding */
735 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, pContext->bufferobject.arrayBuffer->name);
736 /* Save pointers */
737 rc = SSMR3PutU32(pSSM, pContext->bufferobject.arrayBuffer->name);
738 AssertRCReturn(rc, rc);
739 rc = SSMR3PutU32(pSSM, pContext->bufferobject.elementsBuffer->name);
740 AssertRCReturn(rc, rc);
741 /* Save bound array buffers*/ /*@todo vertexArrayStack*/
742 rc = SSMR3PutU32(pSSM, pContext->client.array.v.buffer->name);
743 AssertRCReturn(rc, rc);
744 rc = SSMR3PutU32(pSSM, pContext->client.array.c.buffer->name);
745 AssertRCReturn(rc, rc);
746 rc = SSMR3PutU32(pSSM, pContext->client.array.f.buffer->name);
747 AssertRCReturn(rc, rc);
748 rc = SSMR3PutU32(pSSM, pContext->client.array.s.buffer->name);
749 AssertRCReturn(rc, rc);
750 rc = SSMR3PutU32(pSSM, pContext->client.array.e.buffer->name);
751 AssertRCReturn(rc, rc);
752 rc = SSMR3PutU32(pSSM, pContext->client.array.i.buffer->name);
753 AssertRCReturn(rc, rc);
754 rc = SSMR3PutU32(pSSM, pContext->client.array.n.buffer->name);
755 AssertRCReturn(rc, rc);
756 for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++)
757 {
758 rc = SSMR3PutU32(pSSM, pContext->client.array.t[i].buffer->name);
759 AssertRCReturn(rc, rc);
760 }
761# ifdef CR_NV_vertex_program
762 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
763 {
764 rc = SSMR3PutU32(pSSM, pContext->client.array.a[i].buffer->name);
765 AssertRCReturn(rc, rc);
766 }
767# endif
768#endif /*CR_ARB_vertex_buffer_object*/
769
770 /* Save pixel/vertex programs */
771 ui32 = crHashtableNumElements(pContext->program.programHash);
772 rc = SSMR3PutU32(pSSM, ui32);
773 AssertRCReturn(rc, rc);
774 /* Save defauls programs */
775 crStateSaveProgramCB(0, pContext->program.defaultVertexProgram, pSSM);
776 crStateSaveProgramCB(0, pContext->program.defaultFragmentProgram, pSSM);
777 /* Save all the rest */
778 crHashtableWalk(pContext->program.programHash, crStateSaveProgramCB, pSSM);
779 /* Save Pointers */
780 rc = SSMR3PutU32(pSSM, pContext->program.currentVertexProgram->id);
781 AssertRCReturn(rc, rc);
782 rc = SSMR3PutU32(pSSM, pContext->program.currentFragmentProgram->id);
783 AssertRCReturn(rc, rc);
784 /* This one is unused it seems*/
785 CRASSERT(!pContext->program.errorString);
786
787#ifdef CR_EXT_framebuffer_object
788 /* Save FBOs */
789 ui32 = crHashtableNumElements(pContext->framebufferobject.framebuffers);
790 rc = SSMR3PutU32(pSSM, ui32);
791 AssertRCReturn(rc, rc);
792 crHashtableWalk(pContext->framebufferobject.framebuffers, crStateSaveFramebuffersCB, pSSM);
793 ui32 = crHashtableNumElements(pContext->framebufferobject.renderbuffers);
794 rc = SSMR3PutU32(pSSM, ui32);
795 AssertRCReturn(rc, rc);
796 crHashtableWalk(pContext->framebufferobject.renderbuffers, crStateSaveRenderbuffersCB, pSSM);
797 rc = SSMR3PutU32(pSSM, pContext->framebufferobject.framebuffer?pContext->framebufferobject.framebuffer->id:0);
798 AssertRCReturn(rc, rc);
799 rc = SSMR3PutU32(pSSM, pContext->framebufferobject.renderbuffer?pContext->framebufferobject.renderbuffer->id:0);
800 AssertRCReturn(rc, rc);
801#endif
802
803 return VINF_SUCCESS;
804}
805
806#define SLC_COPYPTR(ptr) pTmpContext->ptr = pContext->ptr
807#define SLC_ASSSERT_NULL_PTR(ptr) CRASSERT(!pContext->ptr)
808
809int32_t crStateLoadContext(CRContext *pContext, PSSMHANDLE pSSM)
810{
811 CRContext* pTmpContext;
812 int32_t rc, i, j;
813 uint32_t uiNumElems, ui, k;
814 unsigned long key;
815
816 CRASSERT(pContext && pSSM);
817
818 /* This one is rather big for stack allocation and causes macs to crash */
819 pTmpContext = (CRContext*)crAlloc(sizeof(*pTmpContext));
820 if (!pTmpContext)
821 return VERR_NO_MEMORY;
822
823 rc = SSMR3GetMem(pSSM, pTmpContext, sizeof(*pTmpContext));
824 AssertRCReturn(rc, rc);
825
826 SLC_COPYPTR(shared);
827 SLC_COPYPTR(flush_func);
828 SLC_COPYPTR(flush_arg);
829
830 /* We're supposed to be loading into an empty context, so those pointers should be NULL */
831 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
832 {
833 SLC_ASSSERT_NULL_PTR(attrib.enableStack[i].clip);
834 SLC_ASSSERT_NULL_PTR(attrib.enableStack[i].light);
835
836 SLC_ASSSERT_NULL_PTR(attrib.lightingStack[i].light);
837 SLC_ASSSERT_NULL_PTR(attrib.transformStack[i].clip);
838 SLC_ASSSERT_NULL_PTR(attrib.transformStack[i].clipPlane);
839
840 for (j=0; j<GLEVAL_TOT; ++j)
841 {
842 SLC_ASSSERT_NULL_PTR(attrib.evalStack[i].eval1D[j].coeff);
843 SLC_ASSSERT_NULL_PTR(attrib.evalStack[i].eval2D[j].coeff);
844 }
845 }
846
847#ifdef CR_ARB_vertex_buffer_object
848 SLC_COPYPTR(bufferobject.buffers);
849 SLC_COPYPTR(bufferobject.nullBuffer);
850#endif
851
852/*@todo, that should be removed probably as those should hold the offset values, so loading should be fine
853 but better check*/
854#if 0
855#ifdef CR_EXT_compiled_vertex_array
856 SLC_COPYPTR(client.array.v.prevPtr);
857 SLC_COPYPTR(client.array.c.prevPtr);
858 SLC_COPYPTR(client.array.f.prevPtr);
859 SLC_COPYPTR(client.array.s.prevPtr);
860 SLC_COPYPTR(client.array.e.prevPtr);
861 SLC_COPYPTR(client.array.i.prevPtr);
862 SLC_COPYPTR(client.array.n.prevPtr);
863 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
864 {
865 SLC_COPYPTR(client.array.t[i].prevPtr);
866 }
867
868# ifdef CR_NV_vertex_program
869 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
870 {
871 SLC_COPYPTR(client.array.a[i].prevPtr);
872 }
873# endif
874#endif
875#endif
876
877#ifdef CR_ARB_vertex_buffer_object
878 /*That just sets those pointers to NULL*/
879 SLC_COPYPTR(client.array.v.buffer);
880 SLC_COPYPTR(client.array.c.buffer);
881 SLC_COPYPTR(client.array.f.buffer);
882 SLC_COPYPTR(client.array.s.buffer);
883 SLC_COPYPTR(client.array.e.buffer);
884 SLC_COPYPTR(client.array.i.buffer);
885 SLC_COPYPTR(client.array.n.buffer);
886 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
887 {
888 SLC_COPYPTR(client.array.t[i].buffer);
889 }
890# ifdef CR_NV_vertex_program
891 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
892 {
893 SLC_COPYPTR(client.array.a[i].buffer);
894 }
895# endif
896#endif /*CR_ARB_vertex_buffer_object*/
897
898 /*@todo CR_NV_vertex_program*/
899 crStateCopyEvalPtrs1D(pTmpContext->eval.eval1D, pContext->eval.eval1D);
900 crStateCopyEvalPtrs2D(pTmpContext->eval.eval2D, pContext->eval.eval2D);
901
902 SLC_COPYPTR(feedback.buffer); /*@todo*/
903 SLC_COPYPTR(selection.buffer); /*@todo*/
904
905 SLC_COPYPTR(lighting.light);
906
907 /*This one could be tricky if we're loading snapshot on host with different GPU*/
908 SLC_COPYPTR(limits.extensions);
909
910#if CR_ARB_occlusion_query
911 SLC_COPYPTR(occlusion.objects); /*@todo*/
912#endif
913
914 SLC_COPYPTR(program.errorString);
915 SLC_COPYPTR(program.programHash);
916 SLC_COPYPTR(program.defaultVertexProgram);
917 SLC_COPYPTR(program.defaultFragmentProgram);
918
919 /* Texture pointers */
920 for (i=0; i<6; ++i)
921 {
922 SLC_COPYPTR(texture.base1D.level[i]);
923 SLC_COPYPTR(texture.base2D.level[i]);
924 SLC_COPYPTR(texture.base3D.level[i]);
925 SLC_COPYPTR(texture.proxy1D.level[i]);
926 SLC_COPYPTR(texture.proxy2D.level[i]);
927 SLC_COPYPTR(texture.proxy3D.level[i]);
928#ifdef CR_ARB_texture_cube_map
929 SLC_COPYPTR(texture.baseCubeMap.level[i]);
930 SLC_COPYPTR(texture.proxyCubeMap.level[i]);
931#endif
932#ifdef CR_NV_texture_rectangle
933 SLC_COPYPTR(texture.baseRect.level[i]);
934 SLC_COPYPTR(texture.proxyRect.level[i]);
935#endif
936 }
937
938 /* Load transform state */
939 SLC_COPYPTR(transform.clipPlane);
940 SLC_COPYPTR(transform.clip);
941 /* Don't have to worry about pContext->transform.current as it'd be set in crStateSetCurrent call */
942 /*SLC_COPYPTR(transform.currentStack);*/
943 SLC_COPYPTR(transform.modelViewStack.stack);
944 SLC_COPYPTR(transform.projectionStack.stack);
945 SLC_COPYPTR(transform.colorStack.stack);
946
947 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
948 {
949 SLC_COPYPTR(transform.textureStack[i].stack);
950 }
951 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
952 {
953 SLC_COPYPTR(transform.programStack[i].stack);
954 }
955
956 SLC_COPYPTR(framebufferobject.framebuffers);
957 SLC_COPYPTR(framebufferobject.renderbuffers);
958
959 /* Have to preserve original context id */
960 CRASSERT(pTmpContext->id == pContext->id);
961 /* Copy ordinary state to real context */
962 crMemcpy(pContext, pTmpContext, sizeof(*pTmpContext));
963 crFree(pTmpContext);
964 pTmpContext = NULL;
965
966 /* Now deal with pointers */
967
968 /* Load transform state */
969 rc = SSMR3GetMem(pSSM, pContext->transform.clipPlane, sizeof(GLvectord)*CR_MAX_CLIP_PLANES);
970 AssertRCReturn(rc, rc);
971 rc = SSMR3GetMem(pSSM, pContext->transform.clip, sizeof(GLboolean)*CR_MAX_CLIP_PLANES);
972 AssertRCReturn(rc, rc);
973 rc = crStateLoadMatrixStack(&pContext->transform.modelViewStack, pSSM);
974 AssertRCReturn(rc, rc);
975 rc = crStateLoadMatrixStack(&pContext->transform.projectionStack, pSSM);
976 AssertRCReturn(rc, rc);
977 rc = crStateLoadMatrixStack(&pContext->transform.colorStack, pSSM);
978 AssertRCReturn(rc, rc);
979 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
980 {
981 rc = crStateLoadMatrixStack(&pContext->transform.textureStack[i], pSSM);
982 AssertRCReturn(rc, rc);
983 }
984 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
985 {
986 rc = crStateLoadMatrixStack(&pContext->transform.programStack[i], pSSM);
987 AssertRCReturn(rc, rc);
988 }
989
990 /* Load Textures */
991 rc = crStateLoadTextureObjData(&pContext->texture.base1D, pSSM);
992 AssertRCReturn(rc, rc);
993 rc = crStateLoadTextureObjData(&pContext->texture.base2D, pSSM);
994 AssertRCReturn(rc, rc);
995 rc = crStateLoadTextureObjData(&pContext->texture.base3D, pSSM);
996 AssertRCReturn(rc, rc);
997 rc = crStateLoadTextureObjData(&pContext->texture.proxy1D, pSSM);
998 AssertRCReturn(rc, rc);
999 rc = crStateLoadTextureObjData(&pContext->texture.proxy2D, pSSM);
1000 AssertRCReturn(rc, rc);
1001 rc = crStateLoadTextureObjData(&pContext->texture.proxy3D, pSSM);
1002 AssertRCReturn(rc, rc);
1003#ifdef CR_ARB_texture_cube_map
1004 rc = crStateLoadTextureObjData(&pContext->texture.baseCubeMap, pSSM);
1005 AssertRCReturn(rc, rc);
1006 rc = crStateLoadTextureObjData(&pContext->texture.proxyCubeMap, pSSM);
1007 AssertRCReturn(rc, rc);
1008#endif
1009#ifdef CR_NV_texture_rectangle
1010 rc = crStateLoadTextureObjData(&pContext->texture.baseRect, pSSM);
1011 AssertRCReturn(rc, rc);
1012 rc = crStateLoadTextureObjData(&pContext->texture.proxyRect, pSSM);
1013 AssertRCReturn(rc, rc);
1014#endif
1015
1016 /* Load shared textures */
1017 CRASSERT(pContext->shared && pContext->shared->textureTable);
1018 rc = SSMR3GetU32(pSSM, &uiNumElems);
1019 AssertRCReturn(rc, rc);
1020 for (ui=0; ui<uiNumElems; ++ui)
1021 {
1022 CRTextureObj *pTexture;
1023
1024 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
1025 AssertRCReturn(rc, rc);
1026
1027 pTexture = (CRTextureObj *) crCalloc(sizeof(CRTextureObj));
1028 if (!pTexture) return VERR_NO_MEMORY;
1029
1030 rc = SSMR3GetMem(pSSM, pTexture, sizeof(*pTexture));
1031 AssertRCReturn(rc, rc);
1032
1033 //DIRTY(pTexture->dirty, pContext->neg_bitid);
1034 //DIRTY(pTexture->imageBit, pContext->neg_bitid);
1035
1036 /*allocate actual memory*/
1037 for (i=0; i<6; ++i) {
1038 pTexture->level[i] = (CRTextureLevel *) crCalloc(sizeof(CRTextureLevel) * MAX_MIPMAP_LEVELS);
1039 if (!pTexture->level[i]) return VERR_NO_MEMORY;
1040 }
1041
1042 rc = crStateLoadTextureObjData(pTexture, pSSM);
1043 AssertRCReturn(rc, rc);
1044
1045 crHashtableAdd(pContext->shared->textureTable, key, pTexture);
1046 }
1047
1048 /* Load current texture pointers */
1049 for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
1050 {
1051 rc = crStateLoadTexUnitCurrentTexturePtrs(&pContext->texture.unit[i], pContext, pSSM);
1052 AssertRCReturn(rc, rc);
1053 }
1054 //FILLDIRTY(GetCurrentBits()->texture.dirty);
1055
1056 /* Mark textures for resending to GPU */
1057 pContext->texture.bResyncNeeded = GL_TRUE;
1058
1059 /* Load lights */
1060 CRASSERT(pContext->lighting.light);
1061 rc = SSMR3GetMem(pSSM, pContext->lighting.light, CR_MAX_LIGHTS * sizeof(*pContext->lighting.light));
1062 AssertRCReturn(rc, rc);
1063
1064 /* Load attrib stack*/
1065 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
1066 {
1067 if (pContext->attrib.enableStack[i].clip)
1068 {
1069 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.enableStack[i].clip,
1070 pContext->limits.maxClipPlanes*sizeof(GLboolean));
1071 AssertRCReturn(rc, rc);
1072 }
1073
1074 if (pContext->attrib.enableStack[i].light)
1075 {
1076 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.enableStack[i].light,
1077 pContext->limits.maxLights*sizeof(GLboolean));
1078 AssertRCReturn(rc, rc);
1079 }
1080
1081 if (pContext->attrib.lightingStack[i].light)
1082 {
1083 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.lightingStack[i].light,
1084 pContext->limits.maxLights*sizeof(CRLight));
1085 AssertRCReturn(rc, rc);
1086 }
1087
1088 for (k=0; k<pContext->limits.maxTextureUnits; ++k)
1089 {
1090 rc = crStateLoadTexUnitCurrentTexturePtrs(&pContext->attrib.textureStack[i].unit[k], pContext, pSSM);
1091 AssertRCReturn(rc, rc);
1092 }
1093
1094 if (pContext->attrib.transformStack[i].clip)
1095 {
1096 rc = crStateAllocAndSSMR3GetMem(pSSM, (void*)&pContext->attrib.transformStack[i].clip,
1097 pContext->limits.maxClipPlanes*sizeof(GLboolean));
1098 AssertRCReturn(rc, rc);
1099 }
1100
1101 if (pContext->attrib.transformStack[i].clipPlane)
1102 {
1103 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.transformStack[i].clipPlane,
1104 pContext->limits.maxClipPlanes*sizeof(GLvectord));
1105 AssertRCReturn(rc, rc);
1106 }
1107 rc = crSateLoadEvalCoeffs1D(pContext->attrib.evalStack[i].eval1D, GL_TRUE, pSSM);
1108 AssertRCReturn(rc, rc);
1109 rc = crSateLoadEvalCoeffs2D(pContext->attrib.evalStack[i].eval2D, GL_TRUE, pSSM);
1110 AssertRCReturn(rc, rc);
1111 }
1112
1113 /* Load evaluator coeffs */
1114 rc = crSateLoadEvalCoeffs1D(pContext->eval.eval1D, GL_FALSE, pSSM);
1115 AssertRCReturn(rc, rc);
1116 rc = crSateLoadEvalCoeffs2D(pContext->eval.eval2D, GL_FALSE, pSSM);
1117 AssertRCReturn(rc, rc);
1118
1119 /* Load buffer objects */
1120#ifdef CR_ARB_vertex_buffer_object
1121 rc = SSMR3GetU32(pSSM, &uiNumElems);
1122 AssertRCReturn(rc, rc);
1123 for (ui=0; ui<=uiNumElems; ++ui) /*ui<=uiNumElems to load nullBuffer in same loop*/
1124 {
1125 CRBufferObject *pBufferObj;
1126
1127 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
1128 AssertRCReturn(rc, rc);
1129
1130 /* default one should be already allocated */
1131 if (key==0)
1132 {
1133 pBufferObj = pContext->bufferobject.nullBuffer;
1134 if (!pBufferObj) return VERR_SSM_UNEXPECTED_DATA;
1135 }
1136 else
1137 {
1138 pBufferObj = (CRBufferObject *) crCalloc(sizeof(*pBufferObj));
1139 if (!pBufferObj) return VERR_NO_MEMORY;
1140 }
1141
1142 rc = SSMR3GetMem(pSSM, pBufferObj, sizeof(*pBufferObj));
1143 AssertRCReturn(rc, rc);
1144
1145 if (pBufferObj->data)
1146 {
1147 CRASSERT(pBufferObj->size>0);
1148 pBufferObj->data = crAlloc(pBufferObj->size);
1149 rc = SSMR3GetMem(pSSM, pBufferObj->data, pBufferObj->size);
1150 AssertRCReturn(rc, rc);
1151
1152 //DIRTY(pBufferObj->dirty, pContext->neg_bitid);
1153 //pBufferObj->dirtyStart = 0;
1154 //pBufferObj->dirtyLength = pBufferObj->size;
1155 }
1156 else if (pBufferObj->name!=0 && pBufferObj->size>0)
1157 {
1158 rc = SSMR3GetMem(pSSM, &pBufferObj->data, sizeof(pBufferObj->data));
1159 AssertRCReturn(rc, rc);
1160
1161 if (pBufferObj->data)
1162 {
1163 pBufferObj->data = crAlloc(pBufferObj->size);
1164 rc = SSMR3GetMem(pSSM, pBufferObj->data, pBufferObj->size);
1165 AssertRCReturn(rc, rc);
1166 }
1167 }
1168
1169
1170 if (key!=0)
1171 crHashtableAdd(pContext->bufferobject.buffers, key, pBufferObj);
1172 }
1173 //FILLDIRTY(GetCurrentBits()->bufferobject.dirty);
1174 /* Load pointers */
1175#define CRS_GET_BO(name) (((name)==0) ? (pContext->bufferobject.nullBuffer) : crHashtableSearch(pContext->bufferobject.buffers, name))
1176 rc = SSMR3GetU32(pSSM, &ui);
1177 AssertRCReturn(rc, rc);
1178 pContext->bufferobject.arrayBuffer = CRS_GET_BO(ui);
1179 rc = SSMR3GetU32(pSSM, &ui);
1180 AssertRCReturn(rc, rc);
1181 pContext->bufferobject.elementsBuffer = CRS_GET_BO(ui);
1182
1183 /* Load bound array buffers*/
1184 rc = SSMR3GetU32(pSSM, &ui);
1185 AssertRCReturn(rc, rc);
1186 pContext->client.array.v.buffer = CRS_GET_BO(ui);
1187
1188 rc = SSMR3GetU32(pSSM, &ui);
1189 AssertRCReturn(rc, rc);
1190 pContext->client.array.c.buffer = CRS_GET_BO(ui);
1191
1192 rc = SSMR3GetU32(pSSM, &ui);
1193 AssertRCReturn(rc, rc);
1194 pContext->client.array.f.buffer = CRS_GET_BO(ui);
1195
1196 rc = SSMR3GetU32(pSSM, &ui);
1197 AssertRCReturn(rc, rc);
1198 pContext->client.array.s.buffer = CRS_GET_BO(ui);
1199
1200 rc = SSMR3GetU32(pSSM, &ui);
1201 AssertRCReturn(rc, rc);
1202 pContext->client.array.e.buffer = CRS_GET_BO(ui);
1203
1204 rc = SSMR3GetU32(pSSM, &ui);
1205 AssertRCReturn(rc, rc);
1206 pContext->client.array.i.buffer = CRS_GET_BO(ui);
1207
1208 rc = SSMR3GetU32(pSSM, &ui);
1209 AssertRCReturn(rc, rc);
1210 pContext->client.array.n.buffer = CRS_GET_BO(ui);
1211
1212 for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++)
1213 {
1214 rc = SSMR3GetU32(pSSM, &ui);
1215 AssertRCReturn(rc, rc);
1216 pContext->client.array.t[i].buffer = CRS_GET_BO(ui);
1217 }
1218# ifdef CR_NV_vertex_program
1219 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
1220 {
1221 rc = SSMR3GetU32(pSSM, &ui);
1222 AssertRCReturn(rc, rc);
1223 pContext->client.array.a[i].buffer = CRS_GET_BO(ui);
1224 }
1225# endif
1226#undef CRS_GET_BO
1227
1228 pContext->bufferobject.bResyncNeeded = GL_TRUE;
1229#endif
1230
1231 /* Load pixel/vertex programs */
1232 rc = SSMR3GetU32(pSSM, &uiNumElems);
1233 AssertRCReturn(rc, rc);
1234 /* Load defauls programs */
1235 rc = crStateLoadProgram(&pContext->program.defaultVertexProgram, pSSM);
1236 AssertRCReturn(rc, rc);
1237 //FILLDIRTY(pContext->program.defaultVertexProgram->dirtyProgram);
1238 rc = crStateLoadProgram(&pContext->program.defaultFragmentProgram, pSSM);
1239 AssertRCReturn(rc, rc);
1240 //FILLDIRTY(pContext->program.defaultFragmentProgram->dirtyProgram);
1241 /* Load all the rest */
1242 for (ui=0; ui<uiNumElems; ++ui)
1243 {
1244 CRProgram *pProgram = NULL;
1245 rc = crStateLoadProgram(&pProgram, pSSM);
1246 AssertRCReturn(rc, rc);
1247 crHashtableAdd(pContext->program.programHash, pProgram->id, pProgram);
1248 //DIRTY(pProgram->dirtyProgram, pContext->neg_bitid);
1249
1250 }
1251 //FILLDIRTY(GetCurrentBits()->program.dirty);
1252 /* Load Pointers */
1253 rc = SSMR3GetU32(pSSM, &ui);
1254 AssertRCReturn(rc, rc);
1255 pContext->program.currentVertexProgram = ui==0 ? pContext->program.defaultVertexProgram
1256 : crHashtableSearch(pContext->program.programHash, ui);
1257 rc = SSMR3GetU32(pSSM, &ui);
1258 AssertRCReturn(rc, rc);
1259 pContext->program.currentFragmentProgram = ui==0 ? pContext->program.defaultFragmentProgram
1260 : crHashtableSearch(pContext->program.programHash, ui);
1261
1262 /* Mark programs for resending to GPU */
1263 pContext->program.bResyncNeeded = GL_TRUE;
1264
1265#ifdef CR_EXT_framebuffer_object
1266 /* Load FBOs */
1267 rc = SSMR3GetU32(pSSM, &uiNumElems);
1268 AssertRCReturn(rc, rc);
1269 for (ui=0; ui<uiNumElems; ++ui)
1270 {
1271 CRFramebufferObject *pFBO;
1272 pFBO = crAlloc(sizeof(*pFBO));
1273 if (!pFBO) return VERR_NO_MEMORY;
1274
1275 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
1276 AssertRCReturn(rc, rc);
1277
1278 rc = SSMR3GetMem(pSSM, pFBO, sizeof(*pFBO));
1279 AssertRCReturn(rc, rc);
1280
1281 crHashtableAdd(pContext->framebufferobject.framebuffers, key, pFBO);
1282 }
1283
1284 rc = SSMR3GetU32(pSSM, &uiNumElems);
1285 AssertRCReturn(rc, rc);
1286 for (ui=0; ui<uiNumElems; ++ui)
1287 {
1288 CRRenderbufferObject *pRBO;
1289 pRBO = crAlloc(sizeof(*pRBO));
1290 if (!pRBO) return VERR_NO_MEMORY;
1291
1292 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
1293 AssertRCReturn(rc, rc);
1294
1295 rc = SSMR3GetMem(pSSM, pRBO, sizeof(*pRBO));
1296 AssertRCReturn(rc, rc);
1297
1298 crHashtableAdd(pContext->framebufferobject.renderbuffers, key, pRBO);
1299 }
1300
1301 rc = SSMR3GetU32(pSSM, &ui);
1302 AssertRCReturn(rc, rc);
1303 pContext->framebufferobject.framebuffer = ui==0 ? NULL
1304 : crHashtableSearch(pContext->framebufferobject.framebuffers, ui);
1305
1306 rc = SSMR3GetU32(pSSM, &ui);
1307 AssertRCReturn(rc, rc);
1308 pContext->framebufferobject.renderbuffer = ui==0 ? NULL
1309 : crHashtableSearch(pContext->framebufferobject.renderbuffers, ui);
1310
1311 /* Mark FBOs/RBOs for resending to GPU */
1312 pContext->framebufferobject.bResyncNeeded = GL_TRUE;
1313#endif
1314
1315 return VINF_SUCCESS;
1316}
Note: See TracBrowser for help on using the repository browser.

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