VirtualBox

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

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

crOpenGL: evil tabs sneaked in

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 38.3 KB
Line 
1/* $Id: state_snapshot.c 16970 2009-02-20 11:29:03Z 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 if (pBufferObj->data)
428 {
429 CRASSERT(pBufferObj->size>0);
430 rc = SSMR3PutMem(pSSM, pBufferObj->data, pBufferObj->size);
431 CRASSERT(rc == VINF_SUCCESS);
432 }
433}
434
435static void crStateSaveProgramCB(unsigned long key, void *data1, void *data2)
436{
437 CRProgram *pProgram = (CRProgram *) data1;
438 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
439 CRProgramSymbol *pSymbol;
440 int32_t rc;
441
442 CRASSERT(pProgram && pSSM);
443
444 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
445 CRASSERT(rc == VINF_SUCCESS);
446 rc = SSMR3PutMem(pSSM, pProgram, sizeof(*pProgram));
447 CRASSERT(rc == VINF_SUCCESS);
448 if (pProgram->string)
449 {
450 CRASSERT(pProgram->length);
451 rc = SSMR3PutMem(pSSM, pProgram->string, pProgram->length);
452 CRASSERT(rc == VINF_SUCCESS);
453 }
454
455 for (pSymbol = pProgram->symbolTable; pSymbol; pSymbol=pSymbol->next)
456 {
457 rc = SSMR3PutMem(pSSM, pSymbol, sizeof(*pSymbol));
458 CRASSERT(rc == VINF_SUCCESS);
459 if (pSymbol->name)
460 {
461 CRASSERT(pSymbol->cbName>0);
462 rc = SSMR3PutMem(pSSM, pSymbol->name, pSymbol->cbName);
463 CRASSERT(rc == VINF_SUCCESS);
464 }
465 }
466}
467
468static int32_t crStateLoadProgram(CRProgram **ppProgram, PSSMHANDLE pSSM)
469{
470 CRProgramSymbol **ppSymbol;
471 int32_t rc;
472 unsigned long key;
473
474 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
475 AssertRCReturn(rc, rc);
476
477 /* we're loading default vertex or pixel program*/
478 if (*ppProgram)
479 {
480 if (key!=0) return VERR_SSM_UNEXPECTED_DATA;
481 }
482 else
483 {
484 *ppProgram = (CRProgram*) crAlloc(sizeof(CRProgram));
485 if (!ppProgram) return VERR_NO_MEMORY;
486 if (key==0) return VERR_SSM_UNEXPECTED_DATA;
487 }
488
489 rc = SSMR3GetMem(pSSM, *ppProgram, sizeof(**ppProgram));
490 AssertRCReturn(rc, rc);
491
492 if ((*ppProgram)->string)
493 {
494 CRASSERT((*ppProgram)->length);
495 (*ppProgram)->string = crAlloc((*ppProgram)->length);
496 if (!(*ppProgram)->string) return VERR_NO_MEMORY;
497 rc = SSMR3GetMem(pSSM, (void*) (*ppProgram)->string, (*ppProgram)->length);
498 AssertRCReturn(rc, rc);
499 }
500
501 for (ppSymbol = &(*ppProgram)->symbolTable; *ppSymbol; ppSymbol=&(*ppSymbol)->next)
502 {
503 *ppSymbol = crAlloc(sizeof(CRProgramSymbol));
504 if (!ppSymbol) return VERR_NO_MEMORY;
505
506 rc = SSMR3GetMem(pSSM, *ppSymbol, sizeof(**ppSymbol));
507 AssertRCReturn(rc, rc);
508
509 if ((*ppSymbol)->name)
510 {
511 CRASSERT((*ppSymbol)->cbName>0);
512 (*ppSymbol)->name = crAlloc((*ppSymbol)->cbName);
513 if (!(*ppSymbol)->name) return VERR_NO_MEMORY;
514
515 rc = SSMR3GetMem(pSSM, (void*) (*ppSymbol)->name, (*ppSymbol)->cbName);
516 AssertRCReturn(rc, rc);
517 }
518 }
519
520 return VINF_SUCCESS;
521}
522
523int32_t crStateSaveContext(CRContext *pContext, PSSMHANDLE pSSM)
524{
525 int32_t rc, i;
526 uint32_t ui32, j;
527
528 CRASSERT(pContext && pSSM);
529
530 rc = SSMR3PutMem(pSSM, pContext, sizeof(*pContext));
531 AssertRCReturn(rc, rc);
532
533 if (crHashtableNumElements(pContext->shared->dlistTable)>0)
534 crWarning("Saving state with %d display lists, unsupported", crHashtableNumElements(pContext->shared->dlistTable));
535
536 if (crHashtableNumElements(pContext->program.programHash)>0)
537 crDebug("Saving state with %d programs", crHashtableNumElements(pContext->program.programHash));
538
539 /* Save transform state */
540 rc = SSMR3PutMem(pSSM, pContext->transform.clipPlane, sizeof(GLvectord)*CR_MAX_CLIP_PLANES);
541 AssertRCReturn(rc, rc);
542 rc = SSMR3PutMem(pSSM, pContext->transform.clip, sizeof(GLboolean)*CR_MAX_CLIP_PLANES);
543 AssertRCReturn(rc, rc);
544 rc = crStateSaveMatrixStack(&pContext->transform.modelViewStack, pSSM);
545 AssertRCReturn(rc, rc);
546 rc = crStateSaveMatrixStack(&pContext->transform.projectionStack, pSSM);
547 AssertRCReturn(rc, rc);
548 rc = crStateSaveMatrixStack(&pContext->transform.colorStack, pSSM);
549 AssertRCReturn(rc, rc);
550 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
551 {
552 rc = crStateSaveMatrixStack(&pContext->transform.textureStack[i], pSSM);
553 AssertRCReturn(rc, rc);
554 }
555 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
556 {
557 rc = crStateSaveMatrixStack(&pContext->transform.programStack[i], pSSM);
558 AssertRCReturn(rc, rc);
559 }
560
561 /* Save textures */
562 rc = crStateSaveTextureObjData(&pContext->texture.base1D, pSSM);
563 AssertRCReturn(rc, rc);
564 rc = crStateSaveTextureObjData(&pContext->texture.base2D, pSSM);
565 AssertRCReturn(rc, rc);
566 rc = crStateSaveTextureObjData(&pContext->texture.base3D, pSSM);
567 AssertRCReturn(rc, rc);
568 rc = crStateSaveTextureObjData(&pContext->texture.proxy1D, pSSM);
569 AssertRCReturn(rc, rc);
570 rc = crStateSaveTextureObjData(&pContext->texture.proxy2D, pSSM);
571 AssertRCReturn(rc, rc);
572 rc = crStateSaveTextureObjData(&pContext->texture.proxy3D, pSSM);
573#ifdef CR_ARB_texture_cube_map
574 rc = crStateSaveTextureObjData(&pContext->texture.baseCubeMap, pSSM);
575 AssertRCReturn(rc, rc);
576 rc = crStateSaveTextureObjData(&pContext->texture.proxyCubeMap, pSSM);
577 AssertRCReturn(rc, rc);
578#endif
579#ifdef CR_NV_texture_rectangle
580 rc = crStateSaveTextureObjData(&pContext->texture.baseRect, pSSM);
581 AssertRCReturn(rc, rc);
582 rc = crStateSaveTextureObjData(&pContext->texture.proxyRect, pSSM);
583 AssertRCReturn(rc, rc);
584#endif
585
586 /* Save shared textures */
587 CRASSERT(pContext->shared && pContext->shared->textureTable);
588 ui32 = crHashtableNumElements(pContext->shared->textureTable);
589 rc = SSMR3PutU32(pSSM, ui32);
590 AssertRCReturn(rc, rc);
591 crHashtableWalk(pContext->shared->textureTable, crStateSaveSharedTextureCB, pSSM);
592
593#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
594 /* Restore previous texture bindings via diff_api */
595 if (ui32)
596 {
597 CRTextureUnit *pTexUnit;
598
599 pTexUnit = &pContext->texture.unit[pContext->texture.curTextureUnit];
600
601 diff_api.BindTexture(GL_TEXTURE_1D, pTexUnit->currentTexture1D->name);
602 diff_api.BindTexture(GL_TEXTURE_2D, pTexUnit->currentTexture2D->name);
603 diff_api.BindTexture(GL_TEXTURE_3D, pTexUnit->currentTexture3D->name);
604#ifdef CR_ARB_texture_cube_map
605 diff_api.BindTexture(GL_TEXTURE_CUBE_MAP_ARB, pTexUnit->currentTextureCubeMap->name);
606#endif
607#ifdef CR_NV_texture_rectangle
608 diff_api.BindTexture(GL_TEXTURE_RECTANGLE_NV, pTexUnit->currentTextureRect->name);
609#endif
610 }
611#endif
612
613 /* Save current texture pointers */
614 for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
615 {
616 rc = crStateSaveTexUnitCurrentTexturePtrs(&pContext->texture.unit[i], pSSM);
617 AssertRCReturn(rc, rc);
618 }
619
620 /* Save lights */
621 CRASSERT(pContext->lighting.light);
622 rc = SSMR3PutMem(pSSM, pContext->lighting.light, CR_MAX_LIGHTS * sizeof(*pContext->lighting.light));
623 AssertRCReturn(rc, rc);
624
625 /* Save attrib stack*/
626 /*@todo could go up to used stack depth here?*/
627 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
628 {
629 if (pContext->attrib.enableStack[i].clip)
630 {
631 rc = SSMR3PutMem(pSSM, pContext->attrib.enableStack[i].clip,
632 pContext->limits.maxClipPlanes*sizeof(GLboolean));
633 AssertRCReturn(rc, rc);
634 }
635
636 if (pContext->attrib.enableStack[i].light)
637 {
638 rc = SSMR3PutMem(pSSM, pContext->attrib.enableStack[i].light,
639 pContext->limits.maxLights*sizeof(GLboolean));
640 AssertRCReturn(rc, rc);
641 }
642
643 if (pContext->attrib.lightingStack[i].light)
644 {
645 rc = SSMR3PutMem(pSSM, pContext->attrib.lightingStack[i].light,
646 pContext->limits.maxLights*sizeof(CRLight));
647 AssertRCReturn(rc, rc);
648 }
649
650 for (j=0; j<pContext->limits.maxTextureUnits; ++j)
651 {
652 rc = crStateSaveTexUnitCurrentTexturePtrs(&pContext->attrib.textureStack[i].unit[j], pSSM);
653 AssertRCReturn(rc, rc);
654 }
655
656 if (pContext->attrib.transformStack[i].clip)
657 {
658 rc = SSMR3PutMem(pSSM, pContext->attrib.transformStack[i].clip,
659 pContext->limits.maxClipPlanes*sizeof(GLboolean));
660 AssertRCReturn(rc, rc);
661 }
662
663 if (pContext->attrib.transformStack[i].clipPlane)
664 {
665 rc = SSMR3PutMem(pSSM, pContext->attrib.transformStack[i].clipPlane,
666 pContext->limits.maxClipPlanes*sizeof(GLvectord));
667 AssertRCReturn(rc, rc);
668 }
669
670 rc = crSateSaveEvalCoeffs1D(pContext->attrib.evalStack[i].eval1D, pSSM);
671 AssertRCReturn(rc, rc);
672 rc = crSateSaveEvalCoeffs2D(pContext->attrib.evalStack[i].eval2D, pSSM);
673 AssertRCReturn(rc, rc);
674 }
675
676 /* Save evaluator coeffs */
677 rc = crSateSaveEvalCoeffs1D(pContext->eval.eval1D, pSSM);
678 AssertRCReturn(rc, rc);
679 rc = crSateSaveEvalCoeffs2D(pContext->eval.eval2D, pSSM);
680 AssertRCReturn(rc, rc);
681
682#ifdef CR_ARB_vertex_buffer_object
683 /* Save buffer objects */
684 ui32 = crHashtableNumElements(pContext->bufferobject.buffers);
685 rc = SSMR3PutU32(pSSM, ui32);
686 AssertRCReturn(rc, rc);
687 /* Save default one*/
688 crStateSaveBufferObjectCB(0, pContext->bufferobject.nullBuffer, pSSM);
689 /* Save all the rest */
690 crHashtableWalk(pContext->bufferobject.buffers, crStateSaveBufferObjectCB, pSSM);
691 /* Save pointers */
692 rc = SSMR3PutU32(pSSM, pContext->bufferobject.arrayBuffer->name);
693 AssertRCReturn(rc, rc);
694 rc = SSMR3PutU32(pSSM, pContext->bufferobject.elementsBuffer->name);
695 AssertRCReturn(rc, rc);
696#endif
697
698 /* Save pixel/vertex programs */
699 ui32 = crHashtableNumElements(pContext->program.programHash);
700 rc = SSMR3PutU32(pSSM, ui32);
701 AssertRCReturn(rc, rc);
702 /* Save defauls programs */
703 crStateSaveProgramCB(0, pContext->program.defaultVertexProgram, pSSM);
704 crStateSaveProgramCB(0, pContext->program.defaultFragmentProgram, pSSM);
705 /* Save all the rest */
706 crHashtableWalk(pContext->program.programHash, crStateSaveProgramCB, pSSM);
707 /* Save Pointers */
708 rc = SSMR3PutU32(pSSM, pContext->program.currentVertexProgram->id);
709 AssertRCReturn(rc, rc);
710 rc = SSMR3PutU32(pSSM, pContext->program.currentFragmentProgram->id);
711 AssertRCReturn(rc, rc);
712 /* This one is unused it seems*/
713 CRASSERT(!pContext->program.errorString);
714
715 return VINF_SUCCESS;
716}
717
718#define SLC_COPYPTR(ptr) pTmpContext->ptr = pContext->ptr
719#define SLC_ASSSERT_NULL_PTR(ptr) CRASSERT(!pContext->ptr)
720
721int32_t crStateLoadContext(CRContext *pContext, PSSMHANDLE pSSM)
722{
723 CRContext* pTmpContext;
724 int32_t rc, i, j;
725 uint32_t uiNumElems, ui, k;
726 unsigned long key;
727
728 CRASSERT(pContext && pSSM);
729
730 /* This one is rather big for stack allocation and causes macs to crash */
731 pTmpContext = (CRContext*)crAlloc(sizeof(*pTmpContext));
732 if (!pTmpContext)
733 return VERR_NO_MEMORY;
734
735 rc = SSMR3GetMem(pSSM, pTmpContext, sizeof(*pTmpContext));
736 AssertRCReturn(rc, rc);
737
738 SLC_COPYPTR(shared);
739 SLC_COPYPTR(flush_func);
740 SLC_COPYPTR(flush_arg);
741
742 /* We're supposed to be loading into an empty context, so those pointers should be NULL */
743 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
744 {
745 SLC_ASSSERT_NULL_PTR(attrib.enableStack[i].clip);
746 SLC_ASSSERT_NULL_PTR(attrib.enableStack[i].light);
747
748 SLC_ASSSERT_NULL_PTR(attrib.lightingStack[i].light);
749 SLC_ASSSERT_NULL_PTR(attrib.transformStack[i].clip);
750 SLC_ASSSERT_NULL_PTR(attrib.transformStack[i].clipPlane);
751
752 for (j=0; j<GLEVAL_TOT; ++j)
753 {
754 SLC_ASSSERT_NULL_PTR(attrib.evalStack[i].eval1D[j].coeff);
755 SLC_ASSSERT_NULL_PTR(attrib.evalStack[i].eval2D[j].coeff);
756 }
757 }
758
759#ifdef CR_ARB_vertex_buffer_object
760 SLC_COPYPTR(bufferobject.buffers);
761 SLC_COPYPTR(bufferobject.nullBuffer);
762#endif
763
764 SLC_COPYPTR(client.array.v.p); /*@todo*/
765 SLC_COPYPTR(client.array.c.p); /*@todo*/
766 SLC_COPYPTR(client.array.f.p); /*@todo*/
767 SLC_COPYPTR(client.array.s.p); /*@todo*/
768 SLC_COPYPTR(client.array.e.p); /*@todo*/
769 SLC_COPYPTR(client.array.i.p); /*@todo*/
770 SLC_COPYPTR(client.array.n.p); /*@todo*/
771 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
772 {
773 SLC_COPYPTR(client.array.t[i].p); /*@todo*/
774 }
775
776#ifdef CR_ARB_vertex_buffer_object2
777 SLC_COPYPTR(client.array.v.buffer); /*@todo*/
778 SLC_COPYPTR(client.array.c.buffer); /*@todo*/
779 SLC_COPYPTR(client.array.f.buffer); /*@todo*/
780 SLC_COPYPTR(client.array.s.buffer); /*@todo*/
781 SLC_COPYPTR(client.array.e.buffer); /*@todo*/
782 SLC_COPYPTR(client.array.i.buffer); /*@todo*/
783 SLC_COPYPTR(client.array.n.buffer); /*@todo*/
784 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
785 {
786 SLC_COPYPTR(client.array.t[i].buffer); /*@todo*/
787 }
788#ifdef CR_NV_vertex_program
789 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++) {
790 {
791 SLC_COPYPTR(client.array.a[i].buffer); /*@todo*/
792 }
793#endif
794#endif /*CR_ARB_vertex_buffer_object2*/
795
796 /*@todo CR_NV_vertex_program*/
797 crStateCopyEvalPtrs1D(pTmpContext->eval.eval1D, pContext->eval.eval1D);
798 crStateCopyEvalPtrs2D(pTmpContext->eval.eval2D, pContext->eval.eval2D);
799
800 SLC_COPYPTR(feedback.buffer); /*@todo*/
801 SLC_COPYPTR(selection.buffer); /*@todo*/
802
803 SLC_COPYPTR(lighting.light);
804
805 /*This one could be tricky if we're loading snapshot on host with different GPU*/
806 SLC_COPYPTR(limits.extensions);
807
808#if CR_ARB_occlusion_query
809 SLC_COPYPTR(occlusion.objects); /*@todo*/
810#endif
811
812 SLC_COPYPTR(program.errorString);
813 SLC_COPYPTR(program.programHash);
814 SLC_COPYPTR(program.defaultVertexProgram);
815 SLC_COPYPTR(program.defaultFragmentProgram);
816
817 /* Texture pointers */
818 for (i=0; i<6; ++i)
819 {
820 SLC_COPYPTR(texture.base1D.level[i]);
821 SLC_COPYPTR(texture.base2D.level[i]);
822 SLC_COPYPTR(texture.base3D.level[i]);
823 SLC_COPYPTR(texture.proxy1D.level[i]);
824 SLC_COPYPTR(texture.proxy2D.level[i]);
825 SLC_COPYPTR(texture.proxy3D.level[i]);
826#ifdef CR_ARB_texture_cube_map
827 SLC_COPYPTR(texture.baseCubeMap.level[i]);
828 SLC_COPYPTR(texture.proxyCubeMap.level[i]);
829#endif
830#ifdef CR_NV_texture_rectangle
831 SLC_COPYPTR(texture.baseRect.level[i]);
832 SLC_COPYPTR(texture.proxyRect.level[i]);
833#endif
834 }
835
836 /* Load transform state */
837 SLC_COPYPTR(transform.clipPlane);
838 SLC_COPYPTR(transform.clip);
839 /* Don't have to worry about pContext->transform.current as it'd be set in crStateSetCurrent call */
840 /*SLC_COPYPTR(transform.currentStack);*/
841 SLC_COPYPTR(transform.modelViewStack.stack);
842 SLC_COPYPTR(transform.projectionStack.stack);
843 SLC_COPYPTR(transform.colorStack.stack);
844
845 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
846 {
847 SLC_COPYPTR(transform.textureStack[i].stack);
848 }
849 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
850 {
851 SLC_COPYPTR(transform.programStack[i].stack);
852 }
853
854 /* Have to preserve original context id */
855 CRASSERT(pTmpContext->id == pContext->id);
856 /* Copy ordinary state to real context */
857 crMemcpy(pContext, pTmpContext, sizeof(*pTmpContext));
858 crFree(pTmpContext);
859 pTmpContext = NULL;
860
861 /* Now deal with pointers */
862
863 /* Load transform state */
864 rc = SSMR3GetMem(pSSM, pContext->transform.clipPlane, sizeof(GLvectord)*CR_MAX_CLIP_PLANES);
865 AssertRCReturn(rc, rc);
866 rc = SSMR3GetMem(pSSM, pContext->transform.clip, sizeof(GLboolean)*CR_MAX_CLIP_PLANES);
867 AssertRCReturn(rc, rc);
868 rc = crStateLoadMatrixStack(&pContext->transform.modelViewStack, pSSM);
869 AssertRCReturn(rc, rc);
870 rc = crStateLoadMatrixStack(&pContext->transform.projectionStack, pSSM);
871 AssertRCReturn(rc, rc);
872 rc = crStateLoadMatrixStack(&pContext->transform.colorStack, pSSM);
873 AssertRCReturn(rc, rc);
874 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
875 {
876 rc = crStateLoadMatrixStack(&pContext->transform.textureStack[i], pSSM);
877 AssertRCReturn(rc, rc);
878 }
879 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
880 {
881 rc = crStateLoadMatrixStack(&pContext->transform.programStack[i], pSSM);
882 AssertRCReturn(rc, rc);
883 }
884
885 /* Load Textures */
886 rc = crStateLoadTextureObjData(&pContext->texture.base1D, pSSM);
887 AssertRCReturn(rc, rc);
888 rc = crStateLoadTextureObjData(&pContext->texture.base2D, pSSM);
889 AssertRCReturn(rc, rc);
890 rc = crStateLoadTextureObjData(&pContext->texture.base3D, pSSM);
891 AssertRCReturn(rc, rc);
892 rc = crStateLoadTextureObjData(&pContext->texture.proxy1D, pSSM);
893 AssertRCReturn(rc, rc);
894 rc = crStateLoadTextureObjData(&pContext->texture.proxy2D, pSSM);
895 AssertRCReturn(rc, rc);
896 rc = crStateLoadTextureObjData(&pContext->texture.proxy3D, pSSM);
897 AssertRCReturn(rc, rc);
898#ifdef CR_ARB_texture_cube_map
899 rc = crStateLoadTextureObjData(&pContext->texture.baseCubeMap, pSSM);
900 AssertRCReturn(rc, rc);
901 rc = crStateLoadTextureObjData(&pContext->texture.proxyCubeMap, pSSM);
902 AssertRCReturn(rc, rc);
903#endif
904#ifdef CR_NV_texture_rectangle
905 rc = crStateLoadTextureObjData(&pContext->texture.baseRect, pSSM);
906 AssertRCReturn(rc, rc);
907 rc = crStateLoadTextureObjData(&pContext->texture.proxyRect, pSSM);
908 AssertRCReturn(rc, rc);
909#endif
910
911 /* Load shared textures */
912 CRASSERT(pContext->shared && pContext->shared->textureTable);
913 rc = SSMR3GetU32(pSSM, &uiNumElems);
914 AssertRCReturn(rc, rc);
915 for (ui=0; ui<uiNumElems; ++ui)
916 {
917 CRTextureObj *pTexture;
918
919 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
920 AssertRCReturn(rc, rc);
921
922 pTexture = (CRTextureObj *) crCalloc(sizeof(CRTextureObj));
923 if (!pTexture) return VERR_NO_MEMORY;
924
925 rc = SSMR3GetMem(pSSM, pTexture, sizeof(*pTexture));
926 AssertRCReturn(rc, rc);
927
928 //DIRTY(pTexture->dirty, pContext->neg_bitid);
929 //DIRTY(pTexture->imageBit, pContext->neg_bitid);
930
931 /*allocate actual memory*/
932 for (i=0; i<6; ++i) {
933 pTexture->level[i] = (CRTextureLevel *) crCalloc(sizeof(CRTextureLevel) * MAX_MIPMAP_LEVELS);
934 if (!pTexture->level[i]) return VERR_NO_MEMORY;
935 }
936
937 rc = crStateLoadTextureObjData(pTexture, pSSM);
938 AssertRCReturn(rc, rc);
939
940 crHashtableAdd(pContext->shared->textureTable, key, pTexture);
941 }
942
943 /* Load current texture pointers */
944 for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
945 {
946 rc = crStateLoadTexUnitCurrentTexturePtrs(&pContext->texture.unit[i], pContext, pSSM);
947 AssertRCReturn(rc, rc);
948 }
949 //FILLDIRTY(GetCurrentBits()->texture.dirty);
950
951 /* Mark textures for resending to GPU */
952 pContext->texture.bResyncNeeded = GL_TRUE;
953
954 /* Load lights */
955 CRASSERT(pContext->lighting.light);
956 rc = SSMR3GetMem(pSSM, pContext->lighting.light, CR_MAX_LIGHTS * sizeof(*pContext->lighting.light));
957 AssertRCReturn(rc, rc);
958
959 /* Load attrib stack*/
960 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
961 {
962 if (pContext->attrib.enableStack[i].clip)
963 {
964 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.enableStack[i].clip,
965 pContext->limits.maxClipPlanes*sizeof(GLboolean));
966 AssertRCReturn(rc, rc);
967 }
968
969 if (pContext->attrib.enableStack[i].light)
970 {
971 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.enableStack[i].light,
972 pContext->limits.maxLights*sizeof(GLboolean));
973 AssertRCReturn(rc, rc);
974 }
975
976 if (pContext->attrib.lightingStack[i].light)
977 {
978 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.lightingStack[i].light,
979 pContext->limits.maxLights*sizeof(CRLight));
980 AssertRCReturn(rc, rc);
981 }
982
983 for (k=0; k<pContext->limits.maxTextureUnits; ++k)
984 {
985 rc = crStateLoadTexUnitCurrentTexturePtrs(&pContext->attrib.textureStack[i].unit[k], pContext, pSSM);
986 AssertRCReturn(rc, rc);
987 }
988
989 if (pContext->attrib.transformStack[i].clip)
990 {
991 rc = crStateAllocAndSSMR3GetMem(pSSM, (void*)&pContext->attrib.transformStack[i].clip,
992 pContext->limits.maxClipPlanes*sizeof(GLboolean));
993 AssertRCReturn(rc, rc);
994 }
995
996 if (pContext->attrib.transformStack[i].clipPlane)
997 {
998 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.transformStack[i].clipPlane,
999 pContext->limits.maxClipPlanes*sizeof(GLvectord));
1000 AssertRCReturn(rc, rc);
1001 }
1002 rc = crSateLoadEvalCoeffs1D(pContext->attrib.evalStack[i].eval1D, GL_TRUE, pSSM);
1003 AssertRCReturn(rc, rc);
1004 rc = crSateLoadEvalCoeffs2D(pContext->attrib.evalStack[i].eval2D, GL_TRUE, pSSM);
1005 AssertRCReturn(rc, rc);
1006 }
1007
1008 /* Load evaluator coeffs */
1009 rc = crSateLoadEvalCoeffs1D(pContext->eval.eval1D, GL_FALSE, pSSM);
1010 AssertRCReturn(rc, rc);
1011 rc = crSateLoadEvalCoeffs2D(pContext->eval.eval2D, GL_FALSE, pSSM);
1012 AssertRCReturn(rc, rc);
1013
1014 /* Load buffer objects */
1015#ifdef CR_ARB_vertex_buffer_object
1016 rc = SSMR3GetU32(pSSM, &uiNumElems);
1017 AssertRCReturn(rc, rc);
1018 for (ui=0; ui<=uiNumElems; ++ui) /*ui<=uiNumElems to load nullBuffer in same loop*/
1019 {
1020 CRBufferObject *pBufferObj;
1021
1022 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
1023 AssertRCReturn(rc, rc);
1024
1025 /* default one should be already allocated */
1026 if (key==0)
1027 {
1028 pBufferObj = pContext->bufferobject.nullBuffer;
1029 if (!pBufferObj) return VERR_SSM_UNEXPECTED_DATA;
1030 }
1031 else
1032 {
1033 pBufferObj = (CRBufferObject *) crCalloc(sizeof(*pBufferObj));
1034 if (!pBufferObj) return VERR_NO_MEMORY;
1035 }
1036
1037 rc = SSMR3GetMem(pSSM, pBufferObj, sizeof(*pBufferObj));
1038 AssertRCReturn(rc, rc);
1039
1040 if (pBufferObj->data)
1041 {
1042 CRASSERT(pBufferObj->size>0);
1043 pBufferObj->data = crAlloc(pBufferObj->size);
1044 rc = SSMR3GetMem(pSSM, pBufferObj->data, pBufferObj->size);
1045 AssertRCReturn(rc, rc);
1046
1047 //DIRTY(pBufferObj->dirty, pContext->neg_bitid);
1048 //pBufferObj->dirtyStart = 0;
1049 //pBufferObj->dirtyLength = pBufferObj->size;
1050 }
1051
1052 if (key!=0)
1053 crHashtableAdd(pContext->bufferobject.buffers, key, pBufferObj);
1054 }
1055 //FILLDIRTY(GetCurrentBits()->bufferobject.dirty);
1056 /* Load pointers */
1057 rc = SSMR3GetU32(pSSM, &ui);
1058 AssertRCReturn(rc, rc);
1059 pContext->bufferobject.arrayBuffer = ui==0 ? pContext->bufferobject.nullBuffer
1060 : crHashtableSearch(pContext->bufferobject.buffers, ui);
1061 rc = SSMR3GetU32(pSSM, &ui);
1062 AssertRCReturn(rc, rc);
1063 pContext->bufferobject.elementsBuffer = ui==0 ? pContext->bufferobject.nullBuffer
1064 : crHashtableSearch(pContext->bufferobject.buffers, ui);
1065#endif
1066
1067 /* Load pixel/vertex programs */
1068 rc = SSMR3GetU32(pSSM, &uiNumElems);
1069 AssertRCReturn(rc, rc);
1070 /* Load defauls programs */
1071 rc = crStateLoadProgram(&pContext->program.defaultVertexProgram, pSSM);
1072 AssertRCReturn(rc, rc);
1073 //FILLDIRTY(pContext->program.defaultVertexProgram->dirtyProgram);
1074 rc = crStateLoadProgram(&pContext->program.defaultFragmentProgram, pSSM);
1075 AssertRCReturn(rc, rc);
1076 //FILLDIRTY(pContext->program.defaultFragmentProgram->dirtyProgram);
1077 /* Load all the rest */
1078 for (ui=0; ui<uiNumElems; ++ui)
1079 {
1080 CRProgram *pProgram = NULL;
1081 rc = crStateLoadProgram(&pProgram, pSSM);
1082 AssertRCReturn(rc, rc);
1083 crHashtableAdd(pContext->program.programHash, pProgram->id, pProgram);
1084 //DIRTY(pProgram->dirtyProgram, pContext->neg_bitid);
1085
1086 }
1087 //FILLDIRTY(GetCurrentBits()->program.dirty);
1088 /* Load Pointers */
1089 rc = SSMR3GetU32(pSSM, &ui);
1090 AssertRCReturn(rc, rc);
1091 pContext->program.currentVertexProgram = ui==0 ? pContext->program.defaultVertexProgram
1092 : crHashtableSearch(pContext->program.programHash, ui);
1093 rc = SSMR3GetU32(pSSM, &ui);
1094 AssertRCReturn(rc, rc);
1095 pContext->program.currentFragmentProgram = ui==0 ? pContext->program.defaultFragmentProgram
1096 : crHashtableSearch(pContext->program.programHash, ui);
1097
1098 /* Mark programs for resending to GPU */
1099 pContext->program.bResyncNeeded = GL_TRUE;
1100
1101 return VINF_SUCCESS;
1102}
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