VirtualBox

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

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

typecast to prevent warnings

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 36.3 KB
Line 
1/* $Id: state_snapshot.c 16551 2009-02-06 15:19:05Z 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 "cr_mem.h"
26
27#include <iprt/assert.h>
28#include <iprt/types.h>
29#include <iprt/err.h>
30#include <VBox/err.h>
31
32/* @todo
33 * We have two ways of saving/loading states.
34 *
35 * First which is being used atm, just pure saving/loading of structures.
36 * The drawback is we have to deal with all the pointers around those structures,
37 * we'd have to update this code if we'd change state tracking.
38 * On the bright side it's fast, though it's not really needed as it's not that often operation.
39 * It could also worth to split those functions into appropriate parts,
40 * similar to the way context creation is being done.
41 *
42 * Second way would be to implement full dispatch api table and substitute diff_api during saving/loading.
43 * Then if we implement that api in a similar way to packer/unpacker with a change to store/load
44 * via provided pSSM handle instead of pack buffer,
45 * saving state could be done by simple diffing against empty "dummy" context.
46 * Restoring state in such case would look like unpacking commands from pSSM instead of network buffer.
47 * This would be slower (who cares) but most likely will not require any code changes to support in future.
48 * We will reduce amount of saved data as we'd save only changed state parts, but I doubt it'd be that much.
49 * It could be done for the first way as well, but requires tons of bit checks.
50 */
51
52/*@todo move with the one from state_texture.c to some header*/
53#define MAX_MIPMAP_LEVELS 20
54
55static int32_t crStateAllocAndSSMR3GetMem(PSSMHANDLE pSSM, void **pBuffer, size_t cbBuffer)
56{
57 CRASSERT(pSSM && pBuffer && cbBuffer>0);
58
59 *pBuffer = crAlloc(cbBuffer);
60 if (!*pBuffer)
61 return VERR_NO_MEMORY;
62
63 return SSMR3GetMem(pSSM, *pBuffer, cbBuffer);
64}
65
66static int32_t crStateSaveTextureObjData(CRTextureObj *pTexture, PSSMHANDLE pSSM)
67{
68 int32_t rc, face, i;
69
70 CRASSERT(pTexture && pSSM);
71
72 for (face = 0; face < 6; face++) {
73 CRASSERT(pTexture->level[face]);
74
75 /*@todo, check if safe to go till MAX_MIPMAP_LEVELS intead of TextureState->maxLevel*/
76 for (i = 0; i < 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 }
87 }
88
89 return VINF_SUCCESS;
90}
91
92static int32_t crStateLoadTextureObjData(CRTextureObj *pTexture, PSSMHANDLE pSSM)
93{
94 int32_t rc, face, i;
95
96 CRASSERT(pTexture && pSSM);
97
98 for (face = 0; face < 6; face++) {
99 CRASSERT(pTexture->level[face]);
100
101 for (i = 0; i < MAX_MIPMAP_LEVELS; i++) {
102 CRTextureLevel *ptl = &(pTexture->level[face][i]);
103 CRASSERT(!ptl->img);
104
105 rc = SSMR3GetMem(pSSM, ptl, sizeof(*ptl));
106 AssertRCReturn(rc, rc);
107 if (ptl->img)
108 {
109 CRASSERT(ptl->bytes);
110
111 ptl->img = crAlloc(ptl->bytes);
112 if (!ptl->img) return VERR_NO_MEMORY;
113
114 rc = SSMR3GetMem(pSSM, ptl->img, ptl->bytes);
115 AssertRCReturn(rc, rc);
116 }
117 crStateTextureInitTextureFormat(ptl, ptl->internalFormat);
118
119 //FILLDIRTY(ptl->dirty);
120 }
121 }
122
123 return VINF_SUCCESS;
124}
125
126static void crStateSaveSharedTextureCB(unsigned long key, void *data1, void *data2)
127{
128 CRTextureObj *pTexture = (CRTextureObj *) data1;
129 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
130 int32_t rc;
131
132 CRASSERT(pTexture && pSSM);
133
134 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
135 CRASSERT(rc == VINF_SUCCESS);
136 rc = SSMR3PutMem(pSSM, pTexture, sizeof(*pTexture));
137 CRASSERT(rc == VINF_SUCCESS);
138 rc = crStateSaveTextureObjData(pTexture, pSSM);
139 CRASSERT(rc == VINF_SUCCESS);
140}
141
142static int32_t crStateSaveMatrixStack(CRMatrixStack *pStack, PSSMHANDLE pSSM)
143{
144 return SSMR3PutMem(pSSM, pStack->stack, sizeof(CRmatrix) * pStack->maxDepth);
145}
146
147static int32_t crStateLoadMatrixStack(CRMatrixStack *pStack, PSSMHANDLE pSSM)
148{
149 int32_t rc;
150
151 CRASSERT(pStack && pSSM);
152
153 rc = SSMR3GetMem(pSSM, pStack->stack, sizeof(CRmatrix) * pStack->maxDepth);
154 /* fixup stack top pointer */
155 pStack->top = &pStack->stack[pStack->depth];
156 return rc;
157}
158
159static int32_t crStateSaveTextureObjPtr(CRTextureObj *pTexture, PSSMHANDLE pSSM)
160{
161 /* Current texture pointer can't be NULL for real texture unit states,
162 * but it could be NULL for unused attribute stack depths.
163 */
164 if (pTexture)
165 return SSMR3PutU32(pSSM, pTexture->name);
166 else
167 return VINF_SUCCESS;
168}
169
170static int32_t crStateLoadTextureObjPtr(CRTextureObj **pTexture, CRContext *pContext, GLenum target, PSSMHANDLE pSSM)
171{
172 uint32_t texName;
173 int32_t rc;
174
175 /* We're loading attrib stack with unused state */
176 if (!*pTexture)
177 return VINF_SUCCESS;
178
179 rc = SSMR3GetU32(pSSM, &texName);
180 AssertRCReturn(rc, rc);
181
182 if (texName)
183 {
184 *pTexture = (CRTextureObj *) crHashtableSearch(pContext->shared->textureTable, texName);
185 }
186 else
187 {
188 switch (target)
189 {
190 case GL_TEXTURE_1D:
191 *pTexture = &(pContext->texture.base1D);
192 break;
193 case GL_TEXTURE_2D:
194 *pTexture = &(pContext->texture.base2D);
195 break;
196#ifdef CR_OPENGL_VERSION_1_2
197 case GL_TEXTURE_3D:
198 *pTexture = &(pContext->texture.base3D);
199 break;
200#endif
201#ifdef CR_ARB_texture_cube_map
202 case GL_TEXTURE_CUBE_MAP_ARB:
203 *pTexture = &(pContext->texture.baseCubeMap);
204 break;
205#endif
206#ifdef CR_NV_texture_rectangle
207 case GL_TEXTURE_RECTANGLE_NV:
208 *pTexture = &(pContext->texture.baseRect);
209 break;
210#endif
211 default:
212 crError("LoadTextureObjPtr: Unknown texture target %d", target);
213 }
214 }
215
216 return rc;
217}
218
219static int32_t crStateSaveTexUnitCurrentTexturePtrs(CRTextureUnit *pTexUnit, PSSMHANDLE pSSM)
220{
221 int32_t rc;
222
223 rc = crStateSaveTextureObjPtr(pTexUnit->currentTexture1D, pSSM);
224 AssertRCReturn(rc, rc);
225 rc = crStateSaveTextureObjPtr(pTexUnit->currentTexture2D, pSSM);
226 AssertRCReturn(rc, rc);
227 rc = crStateSaveTextureObjPtr(pTexUnit->currentTexture3D, pSSM);
228 AssertRCReturn(rc, rc);
229#ifdef CR_ARB_texture_cube_map
230 rc = crStateSaveTextureObjPtr(pTexUnit->currentTextureCubeMap, pSSM);
231 AssertRCReturn(rc, rc);
232#endif
233#ifdef CR_NV_texture_rectangle
234 rc = crStateSaveTextureObjPtr(pTexUnit->currentTextureRect, pSSM);
235 AssertRCReturn(rc, rc);
236#endif
237
238 return rc;
239}
240
241static int32_t crStateLoadTexUnitCurrentTexturePtrs(CRTextureUnit *pTexUnit, CRContext *pContext, PSSMHANDLE pSSM)
242{
243 int32_t rc;
244
245 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTexture1D, pContext, GL_TEXTURE_1D, pSSM);
246 AssertRCReturn(rc, rc);
247 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTexture2D, pContext, GL_TEXTURE_1D, pSSM);
248 AssertRCReturn(rc, rc);
249 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTexture3D, pContext, GL_TEXTURE_2D, pSSM);
250 AssertRCReturn(rc, rc);
251#ifdef CR_ARB_texture_cube_map
252 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTextureCubeMap, pContext, GL_TEXTURE_CUBE_MAP_ARB, pSSM);
253 AssertRCReturn(rc, rc);
254#endif
255#ifdef CR_NV_texture_rectangle
256 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTextureRect, pContext, GL_TEXTURE_RECTANGLE_NV, pSSM);
257 AssertRCReturn(rc, rc);
258#endif
259
260 return rc;
261}
262
263static int32_t crSateSaveEvalCoeffs1D(CREvaluator1D *pEval, PSSMHANDLE pSSM)
264{
265 int32_t rc, i;
266
267 for (i=0; i<GLEVAL_TOT; ++i)
268 {
269 if (pEval[i].coeff)
270 {
271 rc = SSMR3PutMem(pSSM, pEval[i].coeff, pEval[i].order * gleval_sizes[i] * sizeof(GLfloat));
272 AssertRCReturn(rc, rc);
273 }
274 }
275
276 return VINF_SUCCESS;
277}
278
279static int32_t crSateSaveEvalCoeffs2D(CREvaluator2D *pEval, PSSMHANDLE pSSM)
280{
281 int32_t rc, i;
282
283 for (i=0; i<GLEVAL_TOT; ++i)
284 {
285 if (pEval[i].coeff)
286 {
287 rc = SSMR3PutMem(pSSM, pEval[i].coeff, pEval[i].uorder * pEval[i].vorder * gleval_sizes[i] * sizeof(GLfloat));
288 AssertRCReturn(rc, rc);
289 }
290 }
291
292 return VINF_SUCCESS;
293}
294
295static int32_t crSateLoadEvalCoeffs1D(CREvaluator1D *pEval, GLboolean bReallocMem, PSSMHANDLE pSSM)
296{
297 int32_t rc, i;
298 size_t size;
299
300 for (i=0; i<GLEVAL_TOT; ++i)
301 {
302 if (pEval[i].coeff)
303 {
304 size = pEval[i].order * gleval_sizes[i] * sizeof(GLfloat);
305 if (bReallocMem)
306 {
307 pEval[i].coeff = (GLfloat*) crAlloc(size);
308 if (!pEval[i].coeff) return VERR_NO_MEMORY;
309 }
310 rc = SSMR3GetMem(pSSM, pEval[i].coeff, size);
311 AssertRCReturn(rc, rc);
312 }
313 }
314
315 return VINF_SUCCESS;
316}
317
318static int32_t crSateLoadEvalCoeffs2D(CREvaluator2D *pEval, GLboolean bReallocMem, PSSMHANDLE pSSM)
319{
320 int32_t rc, i;
321 size_t size;
322
323 for (i=0; i<GLEVAL_TOT; ++i)
324 {
325 if (pEval[i].coeff)
326 {
327 size = pEval[i].uorder * pEval[i].vorder * gleval_sizes[i] * sizeof(GLfloat);
328 if (bReallocMem)
329 {
330 pEval[i].coeff = (GLfloat*) crAlloc(size);
331 if (!pEval[i].coeff) return VERR_NO_MEMORY;
332 }
333 rc = SSMR3GetMem(pSSM, pEval[i].coeff, size);
334 AssertRCReturn(rc, rc);
335 }
336 }
337
338 return VINF_SUCCESS;
339}
340
341static void crStateCopyEvalPtrs1D(CREvaluator1D *pDst, CREvaluator1D *pSrc)
342{
343 int32_t i;
344
345 for (i=0; i<GLEVAL_TOT; ++i)
346 pDst[i].coeff = pSrc[i].coeff;
347
348 /*
349 pDst[GL_MAP1_VERTEX_3-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_VERTEX_3-GL_MAP1_COLOR_4].coeff;
350 pDst[GL_MAP1_VERTEX_4-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_VERTEX_4-GL_MAP1_COLOR_4].coeff;
351 pDst[GL_MAP1_INDEX-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_INDEX-GL_MAP1_COLOR_4].coeff;
352 pDst[GL_MAP1_COLOR_4-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_COLOR_4-GL_MAP1_COLOR_4].coeff;
353 pDst[GL_MAP1_NORMAL-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_NORMAL-GL_MAP1_COLOR_4].coeff;
354 pDst[GL_MAP1_TEXTURE_COORD_1-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_1-GL_MAP1_COLOR_4].coeff;
355 pDst[GL_MAP1_TEXTURE_COORD_2-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_2-GL_MAP1_COLOR_4].coeff;
356 pDst[GL_MAP1_TEXTURE_COORD_3-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_3-GL_MAP1_COLOR_4].coeff;
357 pDst[GL_MAP1_TEXTURE_COORD_4-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_4-GL_MAP1_COLOR_4].coeff;
358 */
359}
360
361static void crStateCopyEvalPtrs2D(CREvaluator2D *pDst, CREvaluator2D *pSrc)
362{
363 int32_t i;
364
365 for (i=0; i<GLEVAL_TOT; ++i)
366 pDst[i].coeff = pSrc[i].coeff;
367
368 /*
369 pDst[GL_MAP2_VERTEX_3-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_VERTEX_3-GL_MAP2_COLOR_4].coeff;
370 pDst[GL_MAP2_VERTEX_4-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_VERTEX_4-GL_MAP2_COLOR_4].coeff;
371 pDst[GL_MAP2_INDEX-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_INDEX-GL_MAP2_COLOR_4].coeff;
372 pDst[GL_MAP2_COLOR_4-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_COLOR_4-GL_MAP2_COLOR_4].coeff;
373 pDst[GL_MAP2_NORMAL-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_NORMAL-GL_MAP2_COLOR_4].coeff;
374 pDst[GL_MAP2_TEXTURE_COORD_1-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_1-GL_MAP2_COLOR_4].coeff;
375 pDst[GL_MAP2_TEXTURE_COORD_2-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_2-GL_MAP2_COLOR_4].coeff;
376 pDst[GL_MAP2_TEXTURE_COORD_3-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_3-GL_MAP2_COLOR_4].coeff;
377 pDst[GL_MAP2_TEXTURE_COORD_4-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_4-GL_MAP2_COLOR_4].coeff;
378 */
379}
380
381static void crStateSaveBufferObjectCB(unsigned long key, void *data1, void *data2)
382{
383 CRBufferObject *pBufferObj = (CRBufferObject *) data1;
384 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
385 int32_t rc;
386
387 CRASSERT(pBufferObj && pSSM);
388
389 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
390 CRASSERT(rc == VINF_SUCCESS);
391 rc = SSMR3PutMem(pSSM, pBufferObj, sizeof(*pBufferObj));
392 CRASSERT(rc == VINF_SUCCESS);
393 if (pBufferObj->data)
394 {
395 CRASSERT(pBufferObj->size>0);
396 rc = SSMR3PutMem(pSSM, pBufferObj->data, pBufferObj->size);
397 CRASSERT(rc == VINF_SUCCESS);
398 }
399}
400
401static void crStateSaveProgramCB(unsigned long key, void *data1, void *data2)
402{
403 CRProgram *pProgram = (CRProgram *) data1;
404 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
405 CRProgramSymbol *pSymbol;
406 int32_t rc;
407
408 CRASSERT(pProgram && pSSM);
409
410 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
411 CRASSERT(rc == VINF_SUCCESS);
412 rc = SSMR3PutMem(pSSM, pProgram, sizeof(*pProgram));
413 CRASSERT(rc == VINF_SUCCESS);
414 if (pProgram->string)
415 {
416 CRASSERT(pProgram->length);
417 rc = SSMR3PutMem(pSSM, pProgram->string, pProgram->length);
418 CRASSERT(rc == VINF_SUCCESS);
419 }
420
421 for (pSymbol = pProgram->symbolTable; pSymbol; pSymbol=pSymbol->next)
422 {
423 rc = SSMR3PutMem(pSSM, pSymbol, sizeof(*pSymbol));
424 CRASSERT(rc == VINF_SUCCESS);
425 if (pSymbol->name)
426 {
427 CRASSERT(pSymbol->cbName>0);
428 rc = SSMR3PutMem(pSSM, pSymbol->name, pSymbol->cbName);
429 CRASSERT(rc == VINF_SUCCESS);
430 }
431 }
432}
433
434static int32_t crStateLoadProgram(CRProgram **ppProgram, PSSMHANDLE pSSM)
435{
436 CRProgramSymbol **ppSymbol;
437 int32_t rc;
438 unsigned long key;
439
440 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
441 AssertRCReturn(rc, rc);
442
443 /* we're loading default vertex or pixel program*/
444 if (*ppProgram)
445 {
446 if (key!=0) return VERR_SSM_UNEXPECTED_DATA;
447 }
448 else
449 {
450 *ppProgram = (CRProgram*) crAlloc(sizeof(CRProgram));
451 if (!ppProgram) return VERR_NO_MEMORY;
452 if (key==0) return VERR_SSM_UNEXPECTED_DATA;
453 }
454
455 rc = SSMR3GetMem(pSSM, *ppProgram, sizeof(**ppProgram));
456 AssertRCReturn(rc, rc);
457
458 if ((*ppProgram)->string)
459 {
460 CRASSERT((*ppProgram)->length);
461 (*ppProgram)->string = crAlloc((*ppProgram)->length);
462 if (!(*ppProgram)->string) return VERR_NO_MEMORY;
463 rc = SSMR3GetMem(pSSM, (void*) (*ppProgram)->string, (*ppProgram)->length);
464 AssertRCReturn(rc, rc);
465 }
466
467 for (ppSymbol = &(*ppProgram)->symbolTable; *ppSymbol; ppSymbol=&(*ppSymbol)->next)
468 {
469 *ppSymbol = crAlloc(sizeof(CRProgramSymbol));
470 if (!ppSymbol) return VERR_NO_MEMORY;
471
472 rc = SSMR3GetMem(pSSM, *ppSymbol, sizeof(**ppSymbol));
473 AssertRCReturn(rc, rc);
474
475 if ((*ppSymbol)->name)
476 {
477 CRASSERT((*ppSymbol)->cbName>0);
478 (*ppSymbol)->name = crAlloc((*ppSymbol)->cbName);
479 if (!(*ppSymbol)->name) return VERR_NO_MEMORY;
480
481 rc = SSMR3GetMem(pSSM, (void*) (*ppSymbol)->name, (*ppSymbol)->cbName);
482 AssertRCReturn(rc, rc);
483 }
484 }
485
486 return VINF_SUCCESS;
487}
488
489int32_t crStateSaveContext(CRContext *pContext, PSSMHANDLE pSSM)
490{
491 int32_t rc, i;
492 uint32_t ui32, j;
493
494 CRASSERT(pContext && pSSM);
495
496 rc = SSMR3PutMem(pSSM, pContext, sizeof(*pContext));
497 AssertRCReturn(rc, rc);
498
499 if (crHashtableNumElements(pContext->shared->dlistTable)>0)
500 crWarning("Saving state with %d display lists, unsupported", crHashtableNumElements(pContext->shared->dlistTable));
501
502 if (crHashtableNumElements(pContext->program.programHash)>0)
503 crDebug("Saving state with %d programs", crHashtableNumElements(pContext->program.programHash));
504
505 /* Save transform state */
506 rc = SSMR3PutMem(pSSM, pContext->transform.clipPlane, sizeof(GLvectord)*CR_MAX_CLIP_PLANES);
507 AssertRCReturn(rc, rc);
508 rc = SSMR3PutMem(pSSM, pContext->transform.clip, sizeof(GLboolean)*CR_MAX_CLIP_PLANES);
509 AssertRCReturn(rc, rc);
510 rc = crStateSaveMatrixStack(&pContext->transform.modelViewStack, pSSM);
511 AssertRCReturn(rc, rc);
512 rc = crStateSaveMatrixStack(&pContext->transform.projectionStack, pSSM);
513 AssertRCReturn(rc, rc);
514 rc = crStateSaveMatrixStack(&pContext->transform.colorStack, pSSM);
515 AssertRCReturn(rc, rc);
516 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
517 {
518 rc = crStateSaveMatrixStack(&pContext->transform.textureStack[i], pSSM);
519 AssertRCReturn(rc, rc);
520 }
521 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
522 {
523 rc = crStateSaveMatrixStack(&pContext->transform.programStack[i], pSSM);
524 AssertRCReturn(rc, rc);
525 }
526
527 /* Save textures */
528 rc = crStateSaveTextureObjData(&pContext->texture.base1D, pSSM);
529 AssertRCReturn(rc, rc);
530 rc = crStateSaveTextureObjData(&pContext->texture.base2D, pSSM);
531 AssertRCReturn(rc, rc);
532 rc = crStateSaveTextureObjData(&pContext->texture.base3D, pSSM);
533 AssertRCReturn(rc, rc);
534 rc = crStateSaveTextureObjData(&pContext->texture.proxy1D, pSSM);
535 AssertRCReturn(rc, rc);
536 rc = crStateSaveTextureObjData(&pContext->texture.proxy2D, pSSM);
537 AssertRCReturn(rc, rc);
538 rc = crStateSaveTextureObjData(&pContext->texture.proxy3D, pSSM);
539#ifdef CR_ARB_texture_cube_map
540 rc = crStateSaveTextureObjData(&pContext->texture.baseCubeMap, pSSM);
541 AssertRCReturn(rc, rc);
542 rc = crStateSaveTextureObjData(&pContext->texture.proxyCubeMap, pSSM);
543 AssertRCReturn(rc, rc);
544#endif
545#ifdef CR_NV_texture_rectangle
546 rc = crStateSaveTextureObjData(&pContext->texture.baseRect, pSSM);
547 AssertRCReturn(rc, rc);
548 rc = crStateSaveTextureObjData(&pContext->texture.proxyRect, pSSM);
549 AssertRCReturn(rc, rc);
550#endif
551
552 /* Save shared textures */
553 CRASSERT(pContext->shared && pContext->shared->textureTable);
554 ui32 = crHashtableNumElements(pContext->shared->textureTable);
555 rc = SSMR3PutU32(pSSM, ui32);
556 AssertRCReturn(rc, rc);
557 crHashtableWalk(pContext->shared->textureTable, crStateSaveSharedTextureCB, pSSM);
558
559 /* Save current texture pointers */
560 for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
561 {
562 rc = crStateSaveTexUnitCurrentTexturePtrs(&pContext->texture.unit[i], pSSM);
563 AssertRCReturn(rc, rc);
564 }
565
566 /* Save lights */
567 CRASSERT(pContext->lighting.light);
568 rc = SSMR3PutMem(pSSM, pContext->lighting.light, CR_MAX_LIGHTS * sizeof(*pContext->lighting.light));
569 AssertRCReturn(rc, rc);
570
571 /* Save attrib stack*/
572 /*@todo could go up to used stack depth here?*/
573 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
574 {
575 if (pContext->attrib.enableStack[i].clip)
576 {
577 rc = SSMR3PutMem(pSSM, pContext->attrib.enableStack[i].clip,
578 pContext->limits.maxClipPlanes*sizeof(GLboolean));
579 AssertRCReturn(rc, rc);
580 }
581
582 if (pContext->attrib.enableStack[i].light)
583 {
584 rc = SSMR3PutMem(pSSM, pContext->attrib.enableStack[i].light,
585 pContext->limits.maxLights*sizeof(GLboolean));
586 AssertRCReturn(rc, rc);
587 }
588
589 if (pContext->attrib.lightingStack[i].light)
590 {
591 rc = SSMR3PutMem(pSSM, pContext->attrib.lightingStack[i].light,
592 pContext->limits.maxLights*sizeof(CRLight));
593 AssertRCReturn(rc, rc);
594 }
595
596 for (j=0; j<pContext->limits.maxTextureUnits; ++j)
597 {
598 rc = crStateSaveTexUnitCurrentTexturePtrs(&pContext->attrib.textureStack[i].unit[j], pSSM);
599 AssertRCReturn(rc, rc);
600 }
601
602 if (pContext->attrib.transformStack[i].clip)
603 {
604 rc = SSMR3PutMem(pSSM, pContext->attrib.transformStack[i].clip,
605 pContext->limits.maxClipPlanes*sizeof(GLboolean));
606 AssertRCReturn(rc, rc);
607 }
608
609 if (pContext->attrib.transformStack[i].clipPlane)
610 {
611 rc = SSMR3PutMem(pSSM, pContext->attrib.transformStack[i].clipPlane,
612 pContext->limits.maxClipPlanes*sizeof(GLvectord));
613 AssertRCReturn(rc, rc);
614 }
615
616 rc = crSateSaveEvalCoeffs1D(pContext->attrib.evalStack[i].eval1D, pSSM);
617 AssertRCReturn(rc, rc);
618 rc = crSateSaveEvalCoeffs2D(pContext->attrib.evalStack[i].eval2D, pSSM);
619 AssertRCReturn(rc, rc);
620 }
621
622 /* Save evaluator coeffs */
623 rc = crSateSaveEvalCoeffs1D(pContext->eval.eval1D, pSSM);
624 AssertRCReturn(rc, rc);
625 rc = crSateSaveEvalCoeffs2D(pContext->eval.eval2D, pSSM);
626 AssertRCReturn(rc, rc);
627
628#ifdef CR_ARB_vertex_buffer_object
629 /* Save buffer objects */
630 ui32 = crHashtableNumElements(pContext->bufferobject.buffers);
631 rc = SSMR3PutU32(pSSM, ui32);
632 AssertRCReturn(rc, rc);
633 /* Save default one*/
634 crStateSaveBufferObjectCB(0, pContext->bufferobject.nullBuffer, pSSM);
635 /* Save all the rest */
636 crHashtableWalk(pContext->bufferobject.buffers, crStateSaveBufferObjectCB, pSSM);
637 /* Save pointers */
638 rc = SSMR3PutU32(pSSM, pContext->bufferobject.arrayBuffer->name);
639 AssertRCReturn(rc, rc);
640 rc = SSMR3PutU32(pSSM, pContext->bufferobject.elementsBuffer->name);
641 AssertRCReturn(rc, rc);
642#endif
643
644 /* Save pixel/vertex programs */
645 ui32 = crHashtableNumElements(pContext->program.programHash);
646 rc = SSMR3PutU32(pSSM, ui32);
647 AssertRCReturn(rc, rc);
648 /* Save defauls programs */
649 crStateSaveProgramCB(0, pContext->program.defaultVertexProgram, pSSM);
650 crStateSaveProgramCB(0, pContext->program.defaultFragmentProgram, pSSM);
651 /* Save all the rest */
652 crHashtableWalk(pContext->program.programHash, crStateSaveProgramCB, pSSM);
653 /* Save Pointers */
654 rc = SSMR3PutU32(pSSM, pContext->program.currentVertexProgram->id);
655 AssertRCReturn(rc, rc);
656 rc = SSMR3PutU32(pSSM, pContext->program.currentFragmentProgram->id);
657 AssertRCReturn(rc, rc);
658 /* This one is unused it seems*/
659 CRASSERT(!pContext->program.errorString);
660
661 return VINF_SUCCESS;
662}
663
664#define SLC_COPYPTR(ptr) pTmpContext->ptr = pContext->ptr
665#define SLC_ASSSERT_NULL_PTR(ptr) CRASSERT(!pContext->ptr)
666
667int32_t crStateLoadContext(CRContext *pContext, PSSMHANDLE pSSM)
668{
669 CRContext* pTmpContext;
670 int32_t rc, i, j;
671 uint32_t uiNumElems, ui, k;
672 unsigned long key;
673
674 CRASSERT(pContext && pSSM);
675
676 /* This one is rather big for stack allocation and causes macs to crash */
677 pTmpContext = (CRContext*)crAlloc(sizeof(*pTmpContext));
678 if (!pTmpContext)
679 return VERR_NO_MEMORY;
680
681 rc = SSMR3GetMem(pSSM, pTmpContext, sizeof(*pTmpContext));
682 AssertRCReturn(rc, rc);
683
684 SLC_COPYPTR(shared);
685 SLC_COPYPTR(flush_func);
686 SLC_COPYPTR(flush_arg);
687
688 /* We're supposed to be loading into an empty context, so those pointers should be NULL */
689 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
690 {
691 SLC_ASSSERT_NULL_PTR(attrib.enableStack[i].clip);
692 SLC_ASSSERT_NULL_PTR(attrib.enableStack[i].light);
693
694 SLC_ASSSERT_NULL_PTR(attrib.lightingStack[i].light);
695 SLC_ASSSERT_NULL_PTR(attrib.transformStack[i].clip);
696 SLC_ASSSERT_NULL_PTR(attrib.transformStack[i].clipPlane);
697
698 for (j=0; j<GLEVAL_TOT; ++j)
699 {
700 SLC_ASSSERT_NULL_PTR(attrib.evalStack[i].eval1D[j].coeff);
701 SLC_ASSSERT_NULL_PTR(attrib.evalStack[i].eval2D[j].coeff);
702 }
703 }
704
705#ifdef CR_ARB_vertex_buffer_object
706 SLC_COPYPTR(bufferobject.buffers);
707 SLC_COPYPTR(bufferobject.nullBuffer);
708#endif
709
710 SLC_COPYPTR(client.array.v.p); /*@todo*/
711 SLC_COPYPTR(client.array.c.p); /*@todo*/
712 SLC_COPYPTR(client.array.f.p); /*@todo*/
713 SLC_COPYPTR(client.array.s.p); /*@todo*/
714 SLC_COPYPTR(client.array.e.p); /*@todo*/
715 SLC_COPYPTR(client.array.i.p); /*@todo*/
716 SLC_COPYPTR(client.array.n.p); /*@todo*/
717 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
718 {
719 SLC_COPYPTR(client.array.t[i].p); /*@todo*/
720 }
721
722#ifdef CR_ARB_vertex_buffer_object2
723 SLC_COPYPTR(client.array.v.buffer); /*@todo*/
724 SLC_COPYPTR(client.array.c.buffer); /*@todo*/
725 SLC_COPYPTR(client.array.f.buffer); /*@todo*/
726 SLC_COPYPTR(client.array.s.buffer); /*@todo*/
727 SLC_COPYPTR(client.array.e.buffer); /*@todo*/
728 SLC_COPYPTR(client.array.i.buffer); /*@todo*/
729 SLC_COPYPTR(client.array.n.buffer); /*@todo*/
730 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
731 {
732 SLC_COPYPTR(client.array.t[i].buffer); /*@todo*/
733 }
734#ifdef CR_NV_vertex_program
735 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++) {
736 {
737 SLC_COPYPTR(client.array.a[i].buffer); /*@todo*/
738 }
739#endif
740#endif /*CR_ARB_vertex_buffer_object2*/
741
742 /*@todo CR_NV_vertex_program*/
743 crStateCopyEvalPtrs1D(pTmpContext->eval.eval1D, pContext->eval.eval1D);
744 crStateCopyEvalPtrs2D(pTmpContext->eval.eval2D, pContext->eval.eval2D);
745
746 SLC_COPYPTR(feedback.buffer); /*@todo*/
747 SLC_COPYPTR(selection.buffer); /*@todo*/
748
749 SLC_COPYPTR(lighting.light);
750
751 /*This one could be tricky if we're loading snapshot on host with different GPU*/
752 SLC_COPYPTR(limits.extensions);
753
754#if CR_ARB_occlusion_query
755 SLC_COPYPTR(occlusion.objects); /*@todo*/
756#endif
757
758 SLC_COPYPTR(program.errorString);
759 SLC_COPYPTR(program.programHash);
760 SLC_COPYPTR(program.defaultVertexProgram);
761 SLC_COPYPTR(program.defaultFragmentProgram);
762
763 /* Texture pointers */
764 for (i=0; i<6; ++i)
765 {
766 SLC_COPYPTR(texture.base1D.level[i]);
767 SLC_COPYPTR(texture.base2D.level[i]);
768 SLC_COPYPTR(texture.base3D.level[i]);
769 SLC_COPYPTR(texture.proxy1D.level[i]);
770 SLC_COPYPTR(texture.proxy2D.level[i]);
771 SLC_COPYPTR(texture.proxy3D.level[i]);
772#ifdef CR_ARB_texture_cube_map
773 SLC_COPYPTR(texture.baseCubeMap.level[i]);
774 SLC_COPYPTR(texture.proxyCubeMap.level[i]);
775#endif
776#ifdef CR_NV_texture_rectangle
777 SLC_COPYPTR(texture.baseRect.level[i]);
778 SLC_COPYPTR(texture.proxyRect.level[i]);
779#endif
780 }
781
782 /* Load transform state */
783 SLC_COPYPTR(transform.clipPlane);
784 SLC_COPYPTR(transform.clip);
785 /* Don't have to worry about pContext->transform.current as it'd be set in crStateSetCurrent call */
786 /*SLC_COPYPTR(transform.currentStack);*/
787 SLC_COPYPTR(transform.modelViewStack.stack);
788 SLC_COPYPTR(transform.projectionStack.stack);
789 SLC_COPYPTR(transform.colorStack.stack);
790
791 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
792 {
793 SLC_COPYPTR(transform.textureStack[i].stack);
794 }
795 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
796 {
797 SLC_COPYPTR(transform.programStack[i].stack);
798 }
799
800 /* Have to preserve original context id */
801 CRASSERT(pTmpContext->id == pContext->id);
802 /* Copy ordinary state to real context */
803 crMemcpy(pContext, pTmpContext, sizeof(*pTmpContext));
804 crFree(pTmpContext);
805 pTmpContext = NULL;
806
807 /* Now deal with pointers */
808
809 /* Load transform state */
810 rc = SSMR3GetMem(pSSM, pContext->transform.clipPlane, sizeof(GLvectord)*CR_MAX_CLIP_PLANES);
811 AssertRCReturn(rc, rc);
812 rc = SSMR3GetMem(pSSM, pContext->transform.clip, sizeof(GLboolean)*CR_MAX_CLIP_PLANES);
813 AssertRCReturn(rc, rc);
814 rc = crStateLoadMatrixStack(&pContext->transform.modelViewStack, pSSM);
815 AssertRCReturn(rc, rc);
816 rc = crStateLoadMatrixStack(&pContext->transform.projectionStack, pSSM);
817 AssertRCReturn(rc, rc);
818 rc = crStateLoadMatrixStack(&pContext->transform.colorStack, pSSM);
819 AssertRCReturn(rc, rc);
820 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
821 {
822 rc = crStateLoadMatrixStack(&pContext->transform.textureStack[i], pSSM);
823 AssertRCReturn(rc, rc);
824 }
825 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
826 {
827 rc = crStateLoadMatrixStack(&pContext->transform.programStack[i], pSSM);
828 AssertRCReturn(rc, rc);
829 }
830
831 /* Load Textures */
832 rc = crStateLoadTextureObjData(&pContext->texture.base1D, pSSM);
833 AssertRCReturn(rc, rc);
834 rc = crStateLoadTextureObjData(&pContext->texture.base2D, pSSM);
835 AssertRCReturn(rc, rc);
836 rc = crStateLoadTextureObjData(&pContext->texture.base3D, pSSM);
837 AssertRCReturn(rc, rc);
838 rc = crStateLoadTextureObjData(&pContext->texture.proxy1D, pSSM);
839 AssertRCReturn(rc, rc);
840 rc = crStateLoadTextureObjData(&pContext->texture.proxy2D, pSSM);
841 AssertRCReturn(rc, rc);
842 rc = crStateLoadTextureObjData(&pContext->texture.proxy3D, pSSM);
843 AssertRCReturn(rc, rc);
844#ifdef CR_ARB_texture_cube_map
845 rc = crStateLoadTextureObjData(&pContext->texture.baseCubeMap, pSSM);
846 AssertRCReturn(rc, rc);
847 rc = crStateLoadTextureObjData(&pContext->texture.proxyCubeMap, pSSM);
848 AssertRCReturn(rc, rc);
849#endif
850#ifdef CR_NV_texture_rectangle
851 rc = crStateLoadTextureObjData(&pContext->texture.baseRect, pSSM);
852 AssertRCReturn(rc, rc);
853 rc = crStateLoadTextureObjData(&pContext->texture.proxyRect, pSSM);
854 AssertRCReturn(rc, rc);
855#endif
856
857 /* Load shared textures */
858 CRASSERT(pContext->shared && pContext->shared->textureTable);
859 rc = SSMR3GetU32(pSSM, &uiNumElems);
860 AssertRCReturn(rc, rc);
861 for (ui=0; ui<uiNumElems; ++ui)
862 {
863 CRTextureObj *pTexture;
864
865 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
866 AssertRCReturn(rc, rc);
867
868 pTexture = (CRTextureObj *) crCalloc(sizeof(CRTextureObj));
869 if (!pTexture) return VERR_NO_MEMORY;
870
871 rc = SSMR3GetMem(pSSM, pTexture, sizeof(*pTexture));
872 AssertRCReturn(rc, rc);
873
874 //DIRTY(pTexture->dirty, pContext->neg_bitid);
875 //DIRTY(pTexture->imageBit, pContext->neg_bitid);
876
877 /*allocate actual memory*/
878 for (i=0; i<6; ++i) {
879 pTexture->level[i] = (CRTextureLevel *) crCalloc(sizeof(CRTextureLevel) * MAX_MIPMAP_LEVELS);
880 if (!pTexture->level[i]) return VERR_NO_MEMORY;
881 }
882
883 rc = crStateLoadTextureObjData(pTexture, pSSM);
884 AssertRCReturn(rc, rc);
885
886 crHashtableAdd(pContext->shared->textureTable, key, pTexture);
887 }
888
889 /* Load current texture pointers */
890 for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
891 {
892 rc = crStateLoadTexUnitCurrentTexturePtrs(&pContext->texture.unit[i], pContext, pSSM);
893 AssertRCReturn(rc, rc);
894 }
895 //FILLDIRTY(GetCurrentBits()->texture.dirty);
896
897 /* Mark textures for resending to GPU */
898 pContext->texture.bResyncNeeded = GL_TRUE;
899
900 /* Load lights */
901 CRASSERT(pContext->lighting.light);
902 rc = SSMR3GetMem(pSSM, pContext->lighting.light, CR_MAX_LIGHTS * sizeof(*pContext->lighting.light));
903 AssertRCReturn(rc, rc);
904
905 /* Load attrib stack*/
906 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
907 {
908 if (pContext->attrib.enableStack[i].clip)
909 {
910 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.enableStack[i].clip,
911 pContext->limits.maxClipPlanes*sizeof(GLboolean));
912 AssertRCReturn(rc, rc);
913 }
914
915 if (pContext->attrib.enableStack[i].light)
916 {
917 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.enableStack[i].light,
918 pContext->limits.maxLights*sizeof(GLboolean));
919 AssertRCReturn(rc, rc);
920 }
921
922 if (pContext->attrib.lightingStack[i].light)
923 {
924 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.lightingStack[i].light,
925 pContext->limits.maxLights*sizeof(CRLight));
926 AssertRCReturn(rc, rc);
927 }
928
929 for (k=0; k<pContext->limits.maxTextureUnits; ++k)
930 {
931 rc = crStateLoadTexUnitCurrentTexturePtrs(&pContext->attrib.textureStack[i].unit[k], pContext, pSSM);
932 AssertRCReturn(rc, rc);
933 }
934
935 if (pContext->attrib.transformStack[i].clip)
936 {
937 rc = crStateAllocAndSSMR3GetMem(pSSM, (void*)&pContext->attrib.transformStack[i].clip,
938 pContext->limits.maxClipPlanes*sizeof(GLboolean));
939 AssertRCReturn(rc, rc);
940 }
941
942 if (pContext->attrib.transformStack[i].clipPlane)
943 {
944 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.transformStack[i].clipPlane,
945 pContext->limits.maxClipPlanes*sizeof(GLvectord));
946 AssertRCReturn(rc, rc);
947 }
948 rc = crSateLoadEvalCoeffs1D(pContext->attrib.evalStack[i].eval1D, GL_TRUE, pSSM);
949 AssertRCReturn(rc, rc);
950 rc = crSateLoadEvalCoeffs2D(pContext->attrib.evalStack[i].eval2D, GL_TRUE, pSSM);
951 AssertRCReturn(rc, rc);
952 }
953
954 /* Load evaluator coeffs */
955 rc = crSateLoadEvalCoeffs1D(pContext->eval.eval1D, GL_FALSE, pSSM);
956 AssertRCReturn(rc, rc);
957 rc = crSateLoadEvalCoeffs2D(pContext->eval.eval2D, GL_FALSE, pSSM);
958 AssertRCReturn(rc, rc);
959
960 /* Load buffer objects */
961#ifdef CR_ARB_vertex_buffer_object
962 rc = SSMR3GetU32(pSSM, &uiNumElems);
963 AssertRCReturn(rc, rc);
964 for (ui=0; ui<=uiNumElems; ++ui) /*ui<=uiNumElems to load nullBuffer in same loop*/
965 {
966 CRBufferObject *pBufferObj;
967
968 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
969 AssertRCReturn(rc, rc);
970
971 /* default one should be already allocated */
972 if (key==0)
973 {
974 pBufferObj = pContext->bufferobject.nullBuffer;
975 if (!pBufferObj) return VERR_SSM_UNEXPECTED_DATA;
976 }
977 else
978 {
979 pBufferObj = (CRBufferObject *) crCalloc(sizeof(*pBufferObj));
980 if (!pBufferObj) return VERR_NO_MEMORY;
981 }
982
983 rc = SSMR3GetMem(pSSM, pBufferObj, sizeof(*pBufferObj));
984 AssertRCReturn(rc, rc);
985
986 if (pBufferObj->data)
987 {
988 CRASSERT(pBufferObj->size>0);
989 pBufferObj->data = crAlloc(pBufferObj->size);
990 rc = SSMR3GetMem(pSSM, pBufferObj->data, pBufferObj->size);
991 AssertRCReturn(rc, rc);
992
993 //DIRTY(pBufferObj->dirty, pContext->neg_bitid);
994 //pBufferObj->dirtyStart = 0;
995 //pBufferObj->dirtyLength = pBufferObj->size;
996 }
997
998 if (key!=0)
999 crHashtableAdd(pContext->bufferobject.buffers, key, pBufferObj);
1000 }
1001 //FILLDIRTY(GetCurrentBits()->bufferobject.dirty);
1002 /* Load pointers */
1003 rc = SSMR3GetU32(pSSM, &ui);
1004 AssertRCReturn(rc, rc);
1005 pContext->bufferobject.arrayBuffer = ui==0 ? pContext->bufferobject.nullBuffer
1006 : crHashtableSearch(pContext->bufferobject.buffers, ui);
1007 rc = SSMR3GetU32(pSSM, &ui);
1008 AssertRCReturn(rc, rc);
1009 pContext->bufferobject.elementsBuffer = ui==0 ? pContext->bufferobject.nullBuffer
1010 : crHashtableSearch(pContext->bufferobject.buffers, ui);
1011#endif
1012
1013 /* Load pixel/vertex programs */
1014 rc = SSMR3GetU32(pSSM, &uiNumElems);
1015 AssertRCReturn(rc, rc);
1016 /* Load defauls programs */
1017 rc = crStateLoadProgram(&pContext->program.defaultVertexProgram, pSSM);
1018 AssertRCReturn(rc, rc);
1019 //FILLDIRTY(pContext->program.defaultVertexProgram->dirtyProgram);
1020 rc = crStateLoadProgram(&pContext->program.defaultFragmentProgram, pSSM);
1021 AssertRCReturn(rc, rc);
1022 //FILLDIRTY(pContext->program.defaultFragmentProgram->dirtyProgram);
1023 /* Load all the rest */
1024 for (ui=0; ui<uiNumElems; ++ui)
1025 {
1026 CRProgram *pProgram = NULL;
1027 rc = crStateLoadProgram(&pProgram, pSSM);
1028 AssertRCReturn(rc, rc);
1029 crHashtableAdd(pContext->program.programHash, pProgram->id, pProgram);
1030 //DIRTY(pProgram->dirtyProgram, pContext->neg_bitid);
1031
1032 }
1033 //FILLDIRTY(GetCurrentBits()->program.dirty);
1034 /* Load Pointers */
1035 rc = SSMR3GetU32(pSSM, &ui);
1036 AssertRCReturn(rc, rc);
1037 pContext->program.currentVertexProgram = ui==0 ? pContext->program.defaultVertexProgram
1038 : crHashtableSearch(pContext->program.programHash, ui);
1039 rc = SSMR3GetU32(pSSM, &ui);
1040 AssertRCReturn(rc, rc);
1041 pContext->program.currentFragmentProgram = ui==0 ? pContext->program.defaultFragmentProgram
1042 : crHashtableSearch(pContext->program.programHash, ui);
1043
1044 /* Mark programs for resending to GPU */
1045 pContext->program.bResyncNeeded = GL_TRUE;
1046
1047 return VINF_SUCCESS;
1048}
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