VirtualBox

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

最後變更 在這個檔案從24684是 24573,由 vboxsync 提交於 15 年 前

build fix

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 56.6 KB
 
1/* $Id: state_snapshot.c 24573 2009-11-11 09:21:09Z 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.alldomusa.eu.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#include "cr_string.h"
28#include <stdio.h>
29
30#include <iprt/assert.h>
31#include <iprt/types.h>
32#include <iprt/err.h>
33#include <VBox/err.h>
34
35/* @todo
36 * We have two ways of saving/loading states.
37 *
38 * First which is being used atm, just pure saving/loading of structures.
39 * The drawback is we have to deal with all the pointers around those structures,
40 * we'd have to update this code if we'd change state tracking.
41 * On the bright side it's fast, though it's not really needed as it's not that often operation.
42 * It could also worth to split those functions into appropriate parts,
43 * similar to the way context creation is being done.
44 *
45 * Second way would be to implement full dispatch api table and substitute diff_api during saving/loading.
46 * Then if we implement that api in a similar way to packer/unpacker with a change to store/load
47 * via provided pSSM handle instead of pack buffer,
48 * saving state could be done by simple diffing against empty "dummy" context.
49 * Restoring state in such case would look like unpacking commands from pSSM instead of network buffer.
50 * This would be slower (who cares) but most likely will not require any code changes to support in future.
51 * We will reduce amount of saved data as we'd save only changed state parts, but I doubt it'd be that much.
52 * It could be done for the first way as well, but requires tons of bit checks.
53 */
54
55/*@todo move with the one from state_texture.c to some header*/
56#define MAX_MIPMAP_LEVELS 20
57
58static int32_t crStateAllocAndSSMR3GetMem(PSSMHANDLE pSSM, void **pBuffer, size_t cbBuffer)
59{
60 CRASSERT(pSSM && pBuffer && cbBuffer>0);
61
62 *pBuffer = crAlloc(cbBuffer);
63 if (!*pBuffer)
64 return VERR_NO_MEMORY;
65
66 return SSMR3GetMem(pSSM, *pBuffer, cbBuffer);
67}
68
69static int32_t crStateSaveTextureObjData(CRTextureObj *pTexture, PSSMHANDLE pSSM)
70{
71 int32_t rc, face, i;
72
73 CRASSERT(pTexture && pSSM);
74
75 for (face = 0; face < 6; face++) {
76 CRASSERT(pTexture->level[face]);
77
78 /*@todo, check if safe to go till MAX_MIPMAP_LEVELS intead of TextureState->maxLevel*/
79 for (i = 0; i < MAX_MIPMAP_LEVELS; i++) {
80 CRTextureLevel *ptl = &(pTexture->level[face][i]);
81 rc = SSMR3PutMem(pSSM, ptl, sizeof(*ptl));
82 AssertRCReturn(rc, rc);
83 if (ptl->img)
84 {
85 CRASSERT(ptl->bytes);
86 rc = SSMR3PutMem(pSSM, ptl->img, ptl->bytes);
87 AssertRCReturn(rc, rc);
88 }
89#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
90 /* Note, this is not a bug.
91 * Even with CR_STATE_NO_TEXTURE_IMAGE_STORE defined, it's possible that ptl->img!=NULL.
92 * For ex. we're saving snapshot right after it was loaded
93 * and some context hasn't been used by the guest application yet
94 * (pContext->texture.bResyncNeeded==GL_TRUE).
95 */
96 else if (ptl->bytes)
97 {
98 char *pImg;
99
100 pImg = crAlloc(ptl->bytes);
101 if (!pImg) return VERR_NO_MEMORY;
102
103 diff_api.BindTexture(pTexture->target, pTexture->name);
104 diff_api.GetTexImage(pTexture->target, i, ptl->format, ptl->type, pImg);
105
106 rc = SSMR3PutMem(pSSM, pImg, ptl->bytes);
107 crFree(pImg);
108 AssertRCReturn(rc, rc);
109 }
110#endif
111 }
112 }
113
114 return VINF_SUCCESS;
115}
116
117static int32_t crStateLoadTextureObjData(CRTextureObj *pTexture, PSSMHANDLE pSSM)
118{
119 int32_t rc, face, i;
120
121 CRASSERT(pTexture && pSSM);
122
123 for (face = 0; face < 6; face++) {
124 CRASSERT(pTexture->level[face]);
125
126 for (i = 0; i < MAX_MIPMAP_LEVELS; i++) {
127 CRTextureLevel *ptl = &(pTexture->level[face][i]);
128 CRASSERT(!ptl->img);
129
130 rc = SSMR3GetMem(pSSM, ptl, sizeof(*ptl));
131 AssertRCReturn(rc, rc);
132 if (ptl->img)
133 {
134 CRASSERT(ptl->bytes);
135
136 ptl->img = crAlloc(ptl->bytes);
137 if (!ptl->img) return VERR_NO_MEMORY;
138
139 rc = SSMR3GetMem(pSSM, ptl->img, ptl->bytes);
140 AssertRCReturn(rc, rc);
141 }
142#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
143 /* Same story as in crStateSaveTextureObjData */
144 else if (ptl->bytes)
145 {
146 ptl->img = crAlloc(ptl->bytes);
147 if (!ptl->img) return VERR_NO_MEMORY;
148
149 rc = SSMR3GetMem(pSSM, ptl->img, ptl->bytes);
150 AssertRCReturn(rc, rc);
151 }
152#endif
153 crStateTextureInitTextureFormat(ptl, ptl->internalFormat);
154
155 //FILLDIRTY(ptl->dirty);
156 }
157 }
158
159 return VINF_SUCCESS;
160}
161
162static void crStateSaveSharedTextureCB(unsigned long key, void *data1, void *data2)
163{
164 CRTextureObj *pTexture = (CRTextureObj *) data1;
165 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
166 int32_t rc;
167
168 CRASSERT(pTexture && pSSM);
169
170 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
171 CRASSERT(rc == VINF_SUCCESS);
172 rc = SSMR3PutMem(pSSM, pTexture, sizeof(*pTexture));
173 CRASSERT(rc == VINF_SUCCESS);
174 rc = crStateSaveTextureObjData(pTexture, pSSM);
175 CRASSERT(rc == VINF_SUCCESS);
176}
177
178static int32_t crStateSaveMatrixStack(CRMatrixStack *pStack, PSSMHANDLE pSSM)
179{
180 return SSMR3PutMem(pSSM, pStack->stack, sizeof(CRmatrix) * pStack->maxDepth);
181}
182
183static int32_t crStateLoadMatrixStack(CRMatrixStack *pStack, PSSMHANDLE pSSM)
184{
185 int32_t rc;
186
187 CRASSERT(pStack && pSSM);
188
189 rc = SSMR3GetMem(pSSM, pStack->stack, sizeof(CRmatrix) * pStack->maxDepth);
190 /* fixup stack top pointer */
191 pStack->top = &pStack->stack[pStack->depth];
192 return rc;
193}
194
195static int32_t crStateSaveTextureObjPtr(CRTextureObj *pTexture, PSSMHANDLE pSSM)
196{
197 /* Current texture pointer can't be NULL for real texture unit states,
198 * but it could be NULL for unused attribute stack depths.
199 */
200 if (pTexture)
201 return SSMR3PutU32(pSSM, pTexture->name);
202 else
203 return VINF_SUCCESS;
204}
205
206static int32_t crStateLoadTextureObjPtr(CRTextureObj **pTexture, CRContext *pContext, GLenum target, PSSMHANDLE pSSM)
207{
208 uint32_t texName;
209 int32_t rc;
210
211 /* We're loading attrib stack with unused state */
212 if (!*pTexture)
213 return VINF_SUCCESS;
214
215 rc = SSMR3GetU32(pSSM, &texName);
216 AssertRCReturn(rc, rc);
217
218 if (texName)
219 {
220 *pTexture = (CRTextureObj *) crHashtableSearch(pContext->shared->textureTable, texName);
221 }
222 else
223 {
224 switch (target)
225 {
226 case GL_TEXTURE_1D:
227 *pTexture = &(pContext->texture.base1D);
228 break;
229 case GL_TEXTURE_2D:
230 *pTexture = &(pContext->texture.base2D);
231 break;
232#ifdef CR_OPENGL_VERSION_1_2
233 case GL_TEXTURE_3D:
234 *pTexture = &(pContext->texture.base3D);
235 break;
236#endif
237#ifdef CR_ARB_texture_cube_map
238 case GL_TEXTURE_CUBE_MAP_ARB:
239 *pTexture = &(pContext->texture.baseCubeMap);
240 break;
241#endif
242#ifdef CR_NV_texture_rectangle
243 case GL_TEXTURE_RECTANGLE_NV:
244 *pTexture = &(pContext->texture.baseRect);
245 break;
246#endif
247 default:
248 crError("LoadTextureObjPtr: Unknown texture target %d", target);
249 }
250 }
251
252 return rc;
253}
254
255static int32_t crStateSaveTexUnitCurrentTexturePtrs(CRTextureUnit *pTexUnit, PSSMHANDLE pSSM)
256{
257 int32_t rc;
258
259 rc = crStateSaveTextureObjPtr(pTexUnit->currentTexture1D, pSSM);
260 AssertRCReturn(rc, rc);
261 rc = crStateSaveTextureObjPtr(pTexUnit->currentTexture2D, pSSM);
262 AssertRCReturn(rc, rc);
263 rc = crStateSaveTextureObjPtr(pTexUnit->currentTexture3D, pSSM);
264 AssertRCReturn(rc, rc);
265#ifdef CR_ARB_texture_cube_map
266 rc = crStateSaveTextureObjPtr(pTexUnit->currentTextureCubeMap, pSSM);
267 AssertRCReturn(rc, rc);
268#endif
269#ifdef CR_NV_texture_rectangle
270 rc = crStateSaveTextureObjPtr(pTexUnit->currentTextureRect, pSSM);
271 AssertRCReturn(rc, rc);
272#endif
273
274 return rc;
275}
276
277static int32_t crStateLoadTexUnitCurrentTexturePtrs(CRTextureUnit *pTexUnit, CRContext *pContext, PSSMHANDLE pSSM)
278{
279 int32_t rc;
280
281 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTexture1D, pContext, GL_TEXTURE_1D, pSSM);
282 AssertRCReturn(rc, rc);
283 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTexture2D, pContext, GL_TEXTURE_1D, pSSM);
284 AssertRCReturn(rc, rc);
285 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTexture3D, pContext, GL_TEXTURE_2D, pSSM);
286 AssertRCReturn(rc, rc);
287#ifdef CR_ARB_texture_cube_map
288 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTextureCubeMap, pContext, GL_TEXTURE_CUBE_MAP_ARB, pSSM);
289 AssertRCReturn(rc, rc);
290#endif
291#ifdef CR_NV_texture_rectangle
292 rc = crStateLoadTextureObjPtr(&pTexUnit->currentTextureRect, pContext, GL_TEXTURE_RECTANGLE_NV, pSSM);
293 AssertRCReturn(rc, rc);
294#endif
295
296 return rc;
297}
298
299static int32_t crSateSaveEvalCoeffs1D(CREvaluator1D *pEval, PSSMHANDLE pSSM)
300{
301 int32_t rc, i;
302
303 for (i=0; i<GLEVAL_TOT; ++i)
304 {
305 if (pEval[i].coeff)
306 {
307 rc = SSMR3PutMem(pSSM, pEval[i].coeff, pEval[i].order * gleval_sizes[i] * sizeof(GLfloat));
308 AssertRCReturn(rc, rc);
309 }
310 }
311
312 return VINF_SUCCESS;
313}
314
315static int32_t crSateSaveEvalCoeffs2D(CREvaluator2D *pEval, PSSMHANDLE pSSM)
316{
317 int32_t rc, i;
318
319 for (i=0; i<GLEVAL_TOT; ++i)
320 {
321 if (pEval[i].coeff)
322 {
323 rc = SSMR3PutMem(pSSM, pEval[i].coeff, pEval[i].uorder * pEval[i].vorder * gleval_sizes[i] * sizeof(GLfloat));
324 AssertRCReturn(rc, rc);
325 }
326 }
327
328 return VINF_SUCCESS;
329}
330
331static int32_t crSateLoadEvalCoeffs1D(CREvaluator1D *pEval, GLboolean bReallocMem, PSSMHANDLE pSSM)
332{
333 int32_t rc, i;
334 size_t size;
335
336 for (i=0; i<GLEVAL_TOT; ++i)
337 {
338 if (pEval[i].coeff)
339 {
340 size = pEval[i].order * gleval_sizes[i] * sizeof(GLfloat);
341 if (bReallocMem)
342 {
343 pEval[i].coeff = (GLfloat*) crAlloc(size);
344 if (!pEval[i].coeff) return VERR_NO_MEMORY;
345 }
346 rc = SSMR3GetMem(pSSM, pEval[i].coeff, size);
347 AssertRCReturn(rc, rc);
348 }
349 }
350
351 return VINF_SUCCESS;
352}
353
354static int32_t crSateLoadEvalCoeffs2D(CREvaluator2D *pEval, GLboolean bReallocMem, PSSMHANDLE pSSM)
355{
356 int32_t rc, i;
357 size_t size;
358
359 for (i=0; i<GLEVAL_TOT; ++i)
360 {
361 if (pEval[i].coeff)
362 {
363 size = pEval[i].uorder * pEval[i].vorder * gleval_sizes[i] * sizeof(GLfloat);
364 if (bReallocMem)
365 {
366 pEval[i].coeff = (GLfloat*) crAlloc(size);
367 if (!pEval[i].coeff) return VERR_NO_MEMORY;
368 }
369 rc = SSMR3GetMem(pSSM, pEval[i].coeff, size);
370 AssertRCReturn(rc, rc);
371 }
372 }
373
374 return VINF_SUCCESS;
375}
376
377static void crStateCopyEvalPtrs1D(CREvaluator1D *pDst, CREvaluator1D *pSrc)
378{
379 int32_t i;
380
381 for (i=0; i<GLEVAL_TOT; ++i)
382 pDst[i].coeff = pSrc[i].coeff;
383
384 /*
385 pDst[GL_MAP1_VERTEX_3-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_VERTEX_3-GL_MAP1_COLOR_4].coeff;
386 pDst[GL_MAP1_VERTEX_4-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_VERTEX_4-GL_MAP1_COLOR_4].coeff;
387 pDst[GL_MAP1_INDEX-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_INDEX-GL_MAP1_COLOR_4].coeff;
388 pDst[GL_MAP1_COLOR_4-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_COLOR_4-GL_MAP1_COLOR_4].coeff;
389 pDst[GL_MAP1_NORMAL-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_NORMAL-GL_MAP1_COLOR_4].coeff;
390 pDst[GL_MAP1_TEXTURE_COORD_1-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_1-GL_MAP1_COLOR_4].coeff;
391 pDst[GL_MAP1_TEXTURE_COORD_2-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_2-GL_MAP1_COLOR_4].coeff;
392 pDst[GL_MAP1_TEXTURE_COORD_3-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_3-GL_MAP1_COLOR_4].coeff;
393 pDst[GL_MAP1_TEXTURE_COORD_4-GL_MAP1_COLOR_4].coeff = pSrc[GL_MAP1_TEXTURE_COORD_4-GL_MAP1_COLOR_4].coeff;
394 */
395}
396
397static void crStateCopyEvalPtrs2D(CREvaluator2D *pDst, CREvaluator2D *pSrc)
398{
399 int32_t i;
400
401 for (i=0; i<GLEVAL_TOT; ++i)
402 pDst[i].coeff = pSrc[i].coeff;
403
404 /*
405 pDst[GL_MAP2_VERTEX_3-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_VERTEX_3-GL_MAP2_COLOR_4].coeff;
406 pDst[GL_MAP2_VERTEX_4-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_VERTEX_4-GL_MAP2_COLOR_4].coeff;
407 pDst[GL_MAP2_INDEX-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_INDEX-GL_MAP2_COLOR_4].coeff;
408 pDst[GL_MAP2_COLOR_4-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_COLOR_4-GL_MAP2_COLOR_4].coeff;
409 pDst[GL_MAP2_NORMAL-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_NORMAL-GL_MAP2_COLOR_4].coeff;
410 pDst[GL_MAP2_TEXTURE_COORD_1-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_1-GL_MAP2_COLOR_4].coeff;
411 pDst[GL_MAP2_TEXTURE_COORD_2-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_2-GL_MAP2_COLOR_4].coeff;
412 pDst[GL_MAP2_TEXTURE_COORD_3-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_3-GL_MAP2_COLOR_4].coeff;
413 pDst[GL_MAP2_TEXTURE_COORD_4-GL_MAP2_COLOR_4].coeff = pSrc[GL_MAP2_TEXTURE_COORD_4-GL_MAP2_COLOR_4].coeff;
414 */
415}
416
417static void crStateSaveBufferObjectCB(unsigned long key, void *data1, void *data2)
418{
419 CRBufferObject *pBufferObj = (CRBufferObject *) data1;
420 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
421 int32_t rc;
422
423 CRASSERT(pBufferObj && pSSM);
424
425 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
426 CRASSERT(rc == VINF_SUCCESS);
427 rc = SSMR3PutMem(pSSM, pBufferObj, sizeof(*pBufferObj));
428 CRASSERT(rc == VINF_SUCCESS);
429
430 if (pBufferObj->data)
431 {
432 /*We could get here even though retainBufferData is false on host side, in case when we're taking snapshot
433 after state load and before this context was ever made current*/
434 CRASSERT(pBufferObj->size>0);
435 rc = SSMR3PutMem(pSSM, pBufferObj->data, pBufferObj->size);
436 CRASSERT(rc == VINF_SUCCESS);
437 }
438 else if (pBufferObj->name!=0 && pBufferObj->size>0)
439 {
440 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, pBufferObj->name);
441 pBufferObj->pointer = diff_api.MapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_ONLY_ARB);
442 rc = SSMR3PutMem(pSSM, &pBufferObj->pointer, sizeof(pBufferObj->pointer));
443 CRASSERT(rc == VINF_SUCCESS);
444 if (pBufferObj->pointer)
445 {
446 rc = SSMR3PutMem(pSSM, pBufferObj->pointer, pBufferObj->size);
447 CRASSERT(rc == VINF_SUCCESS);
448 }
449 diff_api.UnmapBufferARB(GL_ARRAY_BUFFER_ARB);
450 pBufferObj->pointer = NULL;
451 }
452}
453
454static void crStateSaveProgramCB(unsigned long key, void *data1, void *data2)
455{
456 CRProgram *pProgram = (CRProgram *) data1;
457 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
458 CRProgramSymbol *pSymbol;
459 int32_t rc;
460
461 CRASSERT(pProgram && pSSM);
462
463 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
464 CRASSERT(rc == VINF_SUCCESS);
465 rc = SSMR3PutMem(pSSM, pProgram, sizeof(*pProgram));
466 CRASSERT(rc == VINF_SUCCESS);
467 if (pProgram->string)
468 {
469 CRASSERT(pProgram->length);
470 rc = SSMR3PutMem(pSSM, pProgram->string, pProgram->length);
471 CRASSERT(rc == VINF_SUCCESS);
472 }
473
474 for (pSymbol = pProgram->symbolTable; pSymbol; pSymbol=pSymbol->next)
475 {
476 rc = SSMR3PutMem(pSSM, pSymbol, sizeof(*pSymbol));
477 CRASSERT(rc == VINF_SUCCESS);
478 if (pSymbol->name)
479 {
480 CRASSERT(pSymbol->cbName>0);
481 rc = SSMR3PutMem(pSSM, pSymbol->name, pSymbol->cbName);
482 CRASSERT(rc == VINF_SUCCESS);
483 }
484 }
485}
486
487static void crStateSaveFramebuffersCB(unsigned long key, void *data1, void *data2)
488{
489 CRFramebufferObject *pFBO = (CRFramebufferObject*) data1;
490 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
491 int32_t rc;
492
493 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
494 CRASSERT(rc == VINF_SUCCESS);
495
496 rc = SSMR3PutMem(pSSM, pFBO, sizeof(*pFBO));
497 CRASSERT(rc == VINF_SUCCESS);
498}
499
500static void crStateSaveRenderbuffersCB(unsigned long key, void *data1, void *data2)
501{
502 CRRenderbufferObject *pRBO = (CRRenderbufferObject*) data1;
503 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
504 int32_t rc;
505
506 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
507 CRASSERT(rc == VINF_SUCCESS);
508
509 rc = SSMR3PutMem(pSSM, pRBO, sizeof(*pRBO));
510 CRASSERT(rc == VINF_SUCCESS);
511}
512
513static int32_t crStateLoadProgram(CRProgram **ppProgram, PSSMHANDLE pSSM)
514{
515 CRProgramSymbol **ppSymbol;
516 int32_t rc;
517 unsigned long key;
518
519 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
520 AssertRCReturn(rc, rc);
521
522 /* we're loading default vertex or pixel program*/
523 if (*ppProgram)
524 {
525 if (key!=0) return VERR_SSM_UNEXPECTED_DATA;
526 }
527 else
528 {
529 *ppProgram = (CRProgram*) crAlloc(sizeof(CRProgram));
530 if (!ppProgram) return VERR_NO_MEMORY;
531 if (key==0) return VERR_SSM_UNEXPECTED_DATA;
532 }
533
534 rc = SSMR3GetMem(pSSM, *ppProgram, sizeof(**ppProgram));
535 AssertRCReturn(rc, rc);
536
537 if ((*ppProgram)->string)
538 {
539 CRASSERT((*ppProgram)->length);
540 (*ppProgram)->string = crAlloc((*ppProgram)->length);
541 if (!(*ppProgram)->string) return VERR_NO_MEMORY;
542 rc = SSMR3GetMem(pSSM, (void*) (*ppProgram)->string, (*ppProgram)->length);
543 AssertRCReturn(rc, rc);
544 }
545
546 for (ppSymbol = &(*ppProgram)->symbolTable; *ppSymbol; ppSymbol=&(*ppSymbol)->next)
547 {
548 *ppSymbol = crAlloc(sizeof(CRProgramSymbol));
549 if (!ppSymbol) return VERR_NO_MEMORY;
550
551 rc = SSMR3GetMem(pSSM, *ppSymbol, sizeof(**ppSymbol));
552 AssertRCReturn(rc, rc);
553
554 if ((*ppSymbol)->name)
555 {
556 CRASSERT((*ppSymbol)->cbName>0);
557 (*ppSymbol)->name = crAlloc((*ppSymbol)->cbName);
558 if (!(*ppSymbol)->name) return VERR_NO_MEMORY;
559
560 rc = SSMR3GetMem(pSSM, (void*) (*ppSymbol)->name, (*ppSymbol)->cbName);
561 AssertRCReturn(rc, rc);
562 }
563 }
564
565 return VINF_SUCCESS;
566}
567
568static void crStateSaveString(const char *pStr, PSSMHANDLE pSSM)
569{
570 int32_t len;
571 int32_t rc;
572
573 if (pStr)
574 {
575 len = crStrlen(pStr)+1;
576
577 rc = SSMR3PutS32(pSSM, len);
578 CRASSERT(rc == VINF_SUCCESS);
579
580 rc = SSMR3PutMem(pSSM, pStr, len*sizeof(*pStr));
581 CRASSERT(rc == VINF_SUCCESS);
582 }
583 else
584 {
585 rc = SSMR3PutS32(pSSM, 0);
586 CRASSERT(rc == VINF_SUCCESS);
587 }
588}
589
590static char* crStateLoadString(PSSMHANDLE pSSM)
591{
592 int32_t len, rc;
593 char* pStr = NULL;
594
595 rc = SSMR3GetS32(pSSM, &len);
596 CRASSERT(rc == VINF_SUCCESS);
597
598 if (len!=0)
599 {
600 pStr = crAlloc(len*sizeof(*pStr));
601
602 rc = SSMR3GetMem(pSSM, pStr, len*sizeof(*pStr));
603 CRASSERT(rc == VINF_SUCCESS);
604 }
605
606 return pStr;
607}
608
609static void crStateSaveGLSLShaderCB(unsigned long key, void *data1, void *data2)
610{
611 CRGLSLShader *pShader = (CRGLSLShader*) data1;
612 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
613 int32_t rc;
614
615 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
616 CRASSERT(rc == VINF_SUCCESS);
617
618 rc = SSMR3PutMem(pSSM, pShader, sizeof(*pShader));
619 CRASSERT(rc == VINF_SUCCESS);
620
621 if (pShader->source)
622 {
623 crStateSaveString(pShader->source, pSSM);
624 }
625 else
626 {
627 GLint sLen=0;
628 GLchar *source=NULL;
629
630 diff_api.GetShaderiv(pShader->hwid, GL_SHADER_SOURCE_LENGTH, &sLen);
631 if (sLen>0)
632 {
633 source = (GLchar*) crAlloc(sLen);
634 diff_api.GetShaderSource(pShader->hwid, sLen, NULL, source);
635 }
636
637 crStateSaveString(source, pSSM);
638 if (source) crFree(source);
639 }
640}
641
642static CRGLSLShader* crStateLoadGLSLShader(PSSMHANDLE pSSM)
643{
644 CRGLSLShader *pShader;
645 int32_t rc;
646 unsigned long key;
647
648 pShader = crAlloc(sizeof(*pShader));
649 if (!pShader) return NULL;
650
651 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
652 CRASSERT(rc == VINF_SUCCESS);
653
654 rc = SSMR3GetMem(pSSM, pShader, sizeof(*pShader));
655 CRASSERT(rc == VINF_SUCCESS);
656
657 pShader->source = crStateLoadString(pSSM);
658
659 return pShader;
660}
661
662
663static void crStateSaveGLSLShaderKeyCB(unsigned long key, void *data1, void *data2)
664{
665 CRGLSLShader *pShader = (CRGLSLShader*) data1;
666 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
667 int32_t rc;
668
669 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
670 CRASSERT(rc == VINF_SUCCESS);
671}
672
673static void crStateSaveGLSLProgramAttribs(CRGLSLProgramState *pState, PSSMHANDLE pSSM)
674{
675 GLuint i;
676 int32_t rc;
677
678 for (i=0; i<pState->cAttribs; ++i)
679 {
680 rc = SSMR3PutMem(pSSM, &pState->pAttribs[i].index, sizeof(pState->pAttribs[i].index));
681 CRASSERT(rc == VINF_SUCCESS);
682 crStateSaveString(pState->pAttribs[i].name, pSSM);
683 }
684}
685
686static void crStateSaveGLSLProgramCB(unsigned long key, void *data1, void *data2)
687{
688 CRGLSLProgram *pProgram = (CRGLSLProgram*) data1;
689 PSSMHANDLE pSSM = (PSSMHANDLE) data2;
690 int32_t rc;
691 uint32_t ui32;
692 GLint maxUniformLen, activeUniforms=0, uniformsCount=0, i, j;
693 GLchar *name = NULL;
694 GLenum type;
695 GLint size, location;
696
697 rc = SSMR3PutMem(pSSM, &key, sizeof(key));
698 CRASSERT(rc == VINF_SUCCESS);
699
700 rc = SSMR3PutMem(pSSM, pProgram, sizeof(*pProgram));
701 CRASSERT(rc == VINF_SUCCESS);
702
703 ui32 = crHashtableNumElements(pProgram->currentState.attachedShaders);
704 rc = SSMR3PutU32(pSSM, ui32);
705 CRASSERT(rc == VINF_SUCCESS);
706
707 crHashtableWalk(pProgram->currentState.attachedShaders, crStateSaveGLSLShaderKeyCB, pSSM);
708
709 if (pProgram->activeState.attachedShaders)
710 {
711 ui32 = crHashtableNumElements(pProgram->activeState.attachedShaders);
712 rc = SSMR3PutU32(pSSM, ui32);
713 CRASSERT(rc == VINF_SUCCESS);
714 crHashtableWalk(pProgram->currentState.attachedShaders, crStateSaveGLSLShaderCB, pSSM);
715 }
716
717 crStateSaveGLSLProgramAttribs(&pProgram->currentState, pSSM);
718 crStateSaveGLSLProgramAttribs(&pProgram->activeState, pSSM);
719
720 diff_api.GetProgramiv(pProgram->hwid, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformLen);
721 diff_api.GetProgramiv(pProgram->hwid, GL_ACTIVE_UNIFORMS, &activeUniforms);
722
723 if (activeUniforms>0)
724 {
725 name = (GLchar *) crAlloc((maxUniformLen+8)*sizeof(GLchar));
726
727 if (!name)
728 {
729 crWarning("crStateSaveGLSLProgramCB: out of memory");
730 return;
731 }
732 }
733
734 for (i=0; i<activeUniforms; ++i)
735 {
736 diff_api.GetActiveUniform(pProgram->hwid, i, maxUniformLen, NULL, &size, &type, name);
737 uniformsCount += size;
738 }
739 CRASSERT(uniformsCount>=activeUniforms);
740
741 rc = SSMR3PutS32(pSSM, uniformsCount);
742 CRASSERT(rc == VINF_SUCCESS);
743
744 if (activeUniforms>0)
745 {
746 GLfloat fdata[16];
747 GLint idata[16];
748 char *pIndexStr=NULL;
749
750 for (i=0; i<activeUniforms; ++i)
751 {
752 diff_api.GetActiveUniform(pProgram->hwid, i, maxUniformLen, NULL, &size, &type, name);
753
754 if (size>1)
755 {
756 pIndexStr = crStrchr(name, '[');
757 if (!pIndexStr)
758 {
759 pIndexStr = name+crStrlen(name);
760 }
761 }
762
763 for (j=0; j<size; ++j)
764 {
765 if (size>1)
766 {
767 sprintf(pIndexStr, "[%i]", j);
768 location = diff_api.GetUniformLocation(pProgram->hwid, name);
769 }
770 else
771 {
772 location = i;
773 }
774
775 rc = SSMR3PutMem(pSSM, &type, sizeof(type));
776 CRASSERT(rc == VINF_SUCCESS);
777
778 crStateSaveString(name, pSSM);
779
780 if (crStateIsIntUniform(type))
781 {
782 diff_api.GetUniformiv(pProgram->hwid, location, &idata[0]);
783 rc = SSMR3PutMem(pSSM, &idata[0], crStateGetUniformSize(type)*sizeof(idata[0]));
784 CRASSERT(rc == VINF_SUCCESS);
785 }
786 else
787 {
788 diff_api.GetUniformfv(pProgram->hwid, location, &fdata[0]);
789 rc = SSMR3PutMem(pSSM, &fdata[0], crStateGetUniformSize(type)*sizeof(fdata[0]));
790 CRASSERT(rc == VINF_SUCCESS);
791 }
792 }
793 }
794
795 crFree(name);
796 }
797}
798
799int32_t crStateSaveContext(CRContext *pContext, PSSMHANDLE pSSM)
800{
801 int32_t rc, i;
802 uint32_t ui32, j;
803
804 CRASSERT(pContext && pSSM);
805
806 rc = SSMR3PutMem(pSSM, pContext, sizeof(*pContext));
807 AssertRCReturn(rc, rc);
808
809 if (crHashtableNumElements(pContext->shared->dlistTable)>0)
810 crWarning("Saving state with %d display lists, unsupported", crHashtableNumElements(pContext->shared->dlistTable));
811
812 if (crHashtableNumElements(pContext->program.programHash)>0)
813 crDebug("Saving state with %d programs", crHashtableNumElements(pContext->program.programHash));
814
815 /* Save transform state */
816 rc = SSMR3PutMem(pSSM, pContext->transform.clipPlane, sizeof(GLvectord)*CR_MAX_CLIP_PLANES);
817 AssertRCReturn(rc, rc);
818 rc = SSMR3PutMem(pSSM, pContext->transform.clip, sizeof(GLboolean)*CR_MAX_CLIP_PLANES);
819 AssertRCReturn(rc, rc);
820 rc = crStateSaveMatrixStack(&pContext->transform.modelViewStack, pSSM);
821 AssertRCReturn(rc, rc);
822 rc = crStateSaveMatrixStack(&pContext->transform.projectionStack, pSSM);
823 AssertRCReturn(rc, rc);
824 rc = crStateSaveMatrixStack(&pContext->transform.colorStack, pSSM);
825 AssertRCReturn(rc, rc);
826 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
827 {
828 rc = crStateSaveMatrixStack(&pContext->transform.textureStack[i], pSSM);
829 AssertRCReturn(rc, rc);
830 }
831 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
832 {
833 rc = crStateSaveMatrixStack(&pContext->transform.programStack[i], pSSM);
834 AssertRCReturn(rc, rc);
835 }
836
837 /* Save textures */
838 rc = crStateSaveTextureObjData(&pContext->texture.base1D, pSSM);
839 AssertRCReturn(rc, rc);
840 rc = crStateSaveTextureObjData(&pContext->texture.base2D, pSSM);
841 AssertRCReturn(rc, rc);
842 rc = crStateSaveTextureObjData(&pContext->texture.base3D, pSSM);
843 AssertRCReturn(rc, rc);
844 rc = crStateSaveTextureObjData(&pContext->texture.proxy1D, pSSM);
845 AssertRCReturn(rc, rc);
846 rc = crStateSaveTextureObjData(&pContext->texture.proxy2D, pSSM);
847 AssertRCReturn(rc, rc);
848 rc = crStateSaveTextureObjData(&pContext->texture.proxy3D, pSSM);
849#ifdef CR_ARB_texture_cube_map
850 rc = crStateSaveTextureObjData(&pContext->texture.baseCubeMap, pSSM);
851 AssertRCReturn(rc, rc);
852 rc = crStateSaveTextureObjData(&pContext->texture.proxyCubeMap, pSSM);
853 AssertRCReturn(rc, rc);
854#endif
855#ifdef CR_NV_texture_rectangle
856 rc = crStateSaveTextureObjData(&pContext->texture.baseRect, pSSM);
857 AssertRCReturn(rc, rc);
858 rc = crStateSaveTextureObjData(&pContext->texture.proxyRect, pSSM);
859 AssertRCReturn(rc, rc);
860#endif
861
862 /* Save shared textures */
863 CRASSERT(pContext->shared && pContext->shared->textureTable);
864 ui32 = crHashtableNumElements(pContext->shared->textureTable);
865 rc = SSMR3PutU32(pSSM, ui32);
866 AssertRCReturn(rc, rc);
867 crHashtableWalk(pContext->shared->textureTable, crStateSaveSharedTextureCB, pSSM);
868
869#ifdef CR_STATE_NO_TEXTURE_IMAGE_STORE
870 /* Restore previous texture bindings via diff_api */
871 if (ui32)
872 {
873 CRTextureUnit *pTexUnit;
874
875 pTexUnit = &pContext->texture.unit[pContext->texture.curTextureUnit];
876
877 diff_api.BindTexture(GL_TEXTURE_1D, pTexUnit->currentTexture1D->name);
878 diff_api.BindTexture(GL_TEXTURE_2D, pTexUnit->currentTexture2D->name);
879 diff_api.BindTexture(GL_TEXTURE_3D, pTexUnit->currentTexture3D->name);
880#ifdef CR_ARB_texture_cube_map
881 diff_api.BindTexture(GL_TEXTURE_CUBE_MAP_ARB, pTexUnit->currentTextureCubeMap->name);
882#endif
883#ifdef CR_NV_texture_rectangle
884 diff_api.BindTexture(GL_TEXTURE_RECTANGLE_NV, pTexUnit->currentTextureRect->name);
885#endif
886 }
887#endif
888
889 /* Save current texture pointers */
890 for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
891 {
892 rc = crStateSaveTexUnitCurrentTexturePtrs(&pContext->texture.unit[i], pSSM);
893 AssertRCReturn(rc, rc);
894 }
895
896 /* Save lights */
897 CRASSERT(pContext->lighting.light);
898 rc = SSMR3PutMem(pSSM, pContext->lighting.light, CR_MAX_LIGHTS * sizeof(*pContext->lighting.light));
899 AssertRCReturn(rc, rc);
900
901 /* Save attrib stack*/
902 /*@todo could go up to used stack depth here?*/
903 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
904 {
905 if (pContext->attrib.enableStack[i].clip)
906 {
907 rc = SSMR3PutMem(pSSM, pContext->attrib.enableStack[i].clip,
908 pContext->limits.maxClipPlanes*sizeof(GLboolean));
909 AssertRCReturn(rc, rc);
910 }
911
912 if (pContext->attrib.enableStack[i].light)
913 {
914 rc = SSMR3PutMem(pSSM, pContext->attrib.enableStack[i].light,
915 pContext->limits.maxLights*sizeof(GLboolean));
916 AssertRCReturn(rc, rc);
917 }
918
919 if (pContext->attrib.lightingStack[i].light)
920 {
921 rc = SSMR3PutMem(pSSM, pContext->attrib.lightingStack[i].light,
922 pContext->limits.maxLights*sizeof(CRLight));
923 AssertRCReturn(rc, rc);
924 }
925
926 for (j=0; j<pContext->limits.maxTextureUnits; ++j)
927 {
928 rc = crStateSaveTexUnitCurrentTexturePtrs(&pContext->attrib.textureStack[i].unit[j], pSSM);
929 AssertRCReturn(rc, rc);
930 }
931
932 if (pContext->attrib.transformStack[i].clip)
933 {
934 rc = SSMR3PutMem(pSSM, pContext->attrib.transformStack[i].clip,
935 pContext->limits.maxClipPlanes*sizeof(GLboolean));
936 AssertRCReturn(rc, rc);
937 }
938
939 if (pContext->attrib.transformStack[i].clipPlane)
940 {
941 rc = SSMR3PutMem(pSSM, pContext->attrib.transformStack[i].clipPlane,
942 pContext->limits.maxClipPlanes*sizeof(GLvectord));
943 AssertRCReturn(rc, rc);
944 }
945
946 rc = crSateSaveEvalCoeffs1D(pContext->attrib.evalStack[i].eval1D, pSSM);
947 AssertRCReturn(rc, rc);
948 rc = crSateSaveEvalCoeffs2D(pContext->attrib.evalStack[i].eval2D, pSSM);
949 AssertRCReturn(rc, rc);
950 }
951
952 /* Save evaluator coeffs */
953 rc = crSateSaveEvalCoeffs1D(pContext->eval.eval1D, pSSM);
954 AssertRCReturn(rc, rc);
955 rc = crSateSaveEvalCoeffs2D(pContext->eval.eval2D, pSSM);
956 AssertRCReturn(rc, rc);
957
958#ifdef CR_ARB_vertex_buffer_object
959 /* Save buffer objects */
960 ui32 = crHashtableNumElements(pContext->bufferobject.buffers);
961 rc = SSMR3PutU32(pSSM, ui32);
962 AssertRCReturn(rc, rc);
963 /* Save default one*/
964 crStateSaveBufferObjectCB(0, pContext->bufferobject.nullBuffer, pSSM);
965 /* Save all the rest */
966 crHashtableWalk(pContext->bufferobject.buffers, crStateSaveBufferObjectCB, pSSM);
967 /* Restore binding */
968 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, pContext->bufferobject.arrayBuffer->name);
969 /* Save pointers */
970 rc = SSMR3PutU32(pSSM, pContext->bufferobject.arrayBuffer->name);
971 AssertRCReturn(rc, rc);
972 rc = SSMR3PutU32(pSSM, pContext->bufferobject.elementsBuffer->name);
973 AssertRCReturn(rc, rc);
974 /* Save bound array buffers*/ /*@todo vertexArrayStack*/
975 rc = SSMR3PutU32(pSSM, pContext->client.array.v.buffer->name);
976 AssertRCReturn(rc, rc);
977 rc = SSMR3PutU32(pSSM, pContext->client.array.c.buffer->name);
978 AssertRCReturn(rc, rc);
979 rc = SSMR3PutU32(pSSM, pContext->client.array.f.buffer->name);
980 AssertRCReturn(rc, rc);
981 rc = SSMR3PutU32(pSSM, pContext->client.array.s.buffer->name);
982 AssertRCReturn(rc, rc);
983 rc = SSMR3PutU32(pSSM, pContext->client.array.e.buffer->name);
984 AssertRCReturn(rc, rc);
985 rc = SSMR3PutU32(pSSM, pContext->client.array.i.buffer->name);
986 AssertRCReturn(rc, rc);
987 rc = SSMR3PutU32(pSSM, pContext->client.array.n.buffer->name);
988 AssertRCReturn(rc, rc);
989 for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++)
990 {
991 rc = SSMR3PutU32(pSSM, pContext->client.array.t[i].buffer->name);
992 AssertRCReturn(rc, rc);
993 }
994# ifdef CR_NV_vertex_program
995 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
996 {
997 rc = SSMR3PutU32(pSSM, pContext->client.array.a[i].buffer->name);
998 AssertRCReturn(rc, rc);
999 }
1000# endif
1001#endif /*CR_ARB_vertex_buffer_object*/
1002
1003 /* Save pixel/vertex programs */
1004 ui32 = crHashtableNumElements(pContext->program.programHash);
1005 rc = SSMR3PutU32(pSSM, ui32);
1006 AssertRCReturn(rc, rc);
1007 /* Save defauls programs */
1008 crStateSaveProgramCB(0, pContext->program.defaultVertexProgram, pSSM);
1009 crStateSaveProgramCB(0, pContext->program.defaultFragmentProgram, pSSM);
1010 /* Save all the rest */
1011 crHashtableWalk(pContext->program.programHash, crStateSaveProgramCB, pSSM);
1012 /* Save Pointers */
1013 rc = SSMR3PutU32(pSSM, pContext->program.currentVertexProgram->id);
1014 AssertRCReturn(rc, rc);
1015 rc = SSMR3PutU32(pSSM, pContext->program.currentFragmentProgram->id);
1016 AssertRCReturn(rc, rc);
1017 /* This one is unused it seems*/
1018 CRASSERT(!pContext->program.errorString);
1019
1020#ifdef CR_EXT_framebuffer_object
1021 /* Save FBOs */
1022 ui32 = crHashtableNumElements(pContext->framebufferobject.framebuffers);
1023 rc = SSMR3PutU32(pSSM, ui32);
1024 AssertRCReturn(rc, rc);
1025 crHashtableWalk(pContext->framebufferobject.framebuffers, crStateSaveFramebuffersCB, pSSM);
1026 ui32 = crHashtableNumElements(pContext->framebufferobject.renderbuffers);
1027 rc = SSMR3PutU32(pSSM, ui32);
1028 AssertRCReturn(rc, rc);
1029 crHashtableWalk(pContext->framebufferobject.renderbuffers, crStateSaveRenderbuffersCB, pSSM);
1030 rc = SSMR3PutU32(pSSM, pContext->framebufferobject.drawFB?pContext->framebufferobject.drawFB->id:0);
1031 AssertRCReturn(rc, rc);
1032 rc = SSMR3PutU32(pSSM, pContext->framebufferobject.readFB?pContext->framebufferobject.readFB->id:0);
1033 AssertRCReturn(rc, rc);
1034 rc = SSMR3PutU32(pSSM, pContext->framebufferobject.renderbuffer?pContext->framebufferobject.renderbuffer->id:0);
1035 AssertRCReturn(rc, rc);
1036#endif
1037
1038#ifdef CR_OPENGL_VERSION_2_0
1039 /* Save GLSL related info */
1040 ui32 = crHashtableNumElements(pContext->glsl.shaders);
1041 rc = SSMR3PutU32(pSSM, ui32);
1042 AssertRCReturn(rc, rc);
1043 crHashtableWalk(pContext->glsl.shaders, crStateSaveGLSLShaderCB, pSSM);
1044 ui32 = crHashtableNumElements(pContext->glsl.programs);
1045 rc = SSMR3PutU32(pSSM, ui32);
1046 AssertRCReturn(rc, rc);
1047 crHashtableWalk(pContext->glsl.programs, crStateSaveGLSLProgramCB, pSSM);
1048 rc = SSMR3PutU32(pSSM, pContext->glsl.activeProgram?pContext->glsl.activeProgram->id:0);
1049 AssertRCReturn(rc, rc);
1050#endif
1051
1052 return VINF_SUCCESS;
1053}
1054
1055#define SLC_COPYPTR(ptr) pTmpContext->ptr = pContext->ptr
1056#define SLC_ASSSERT_NULL_PTR(ptr) CRASSERT(!pContext->ptr)
1057
1058int32_t crStateLoadContext(CRContext *pContext, PSSMHANDLE pSSM)
1059{
1060 CRContext* pTmpContext;
1061 int32_t rc, i, j;
1062 uint32_t uiNumElems, ui, k;
1063 unsigned long key;
1064
1065 CRASSERT(pContext && pSSM);
1066
1067 /* This one is rather big for stack allocation and causes macs to crash */
1068 pTmpContext = (CRContext*)crAlloc(sizeof(*pTmpContext));
1069 if (!pTmpContext)
1070 return VERR_NO_MEMORY;
1071
1072 rc = SSMR3GetMem(pSSM, pTmpContext, sizeof(*pTmpContext));
1073 AssertRCReturn(rc, rc);
1074
1075 SLC_COPYPTR(shared);
1076 SLC_COPYPTR(flush_func);
1077 SLC_COPYPTR(flush_arg);
1078
1079 /* We're supposed to be loading into an empty context, so those pointers should be NULL */
1080 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
1081 {
1082 SLC_ASSSERT_NULL_PTR(attrib.enableStack[i].clip);
1083 SLC_ASSSERT_NULL_PTR(attrib.enableStack[i].light);
1084
1085 SLC_ASSSERT_NULL_PTR(attrib.lightingStack[i].light);
1086 SLC_ASSSERT_NULL_PTR(attrib.transformStack[i].clip);
1087 SLC_ASSSERT_NULL_PTR(attrib.transformStack[i].clipPlane);
1088
1089 for (j=0; j<GLEVAL_TOT; ++j)
1090 {
1091 SLC_ASSSERT_NULL_PTR(attrib.evalStack[i].eval1D[j].coeff);
1092 SLC_ASSSERT_NULL_PTR(attrib.evalStack[i].eval2D[j].coeff);
1093 }
1094 }
1095
1096#ifdef CR_ARB_vertex_buffer_object
1097 SLC_COPYPTR(bufferobject.buffers);
1098 SLC_COPYPTR(bufferobject.nullBuffer);
1099#endif
1100
1101/*@todo, that should be removed probably as those should hold the offset values, so loading should be fine
1102 but better check*/
1103#if 0
1104#ifdef CR_EXT_compiled_vertex_array
1105 SLC_COPYPTR(client.array.v.prevPtr);
1106 SLC_COPYPTR(client.array.c.prevPtr);
1107 SLC_COPYPTR(client.array.f.prevPtr);
1108 SLC_COPYPTR(client.array.s.prevPtr);
1109 SLC_COPYPTR(client.array.e.prevPtr);
1110 SLC_COPYPTR(client.array.i.prevPtr);
1111 SLC_COPYPTR(client.array.n.prevPtr);
1112 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
1113 {
1114 SLC_COPYPTR(client.array.t[i].prevPtr);
1115 }
1116
1117# ifdef CR_NV_vertex_program
1118 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
1119 {
1120 SLC_COPYPTR(client.array.a[i].prevPtr);
1121 }
1122# endif
1123#endif
1124#endif
1125
1126#ifdef CR_ARB_vertex_buffer_object
1127 /*That just sets those pointers to NULL*/
1128 SLC_COPYPTR(client.array.v.buffer);
1129 SLC_COPYPTR(client.array.c.buffer);
1130 SLC_COPYPTR(client.array.f.buffer);
1131 SLC_COPYPTR(client.array.s.buffer);
1132 SLC_COPYPTR(client.array.e.buffer);
1133 SLC_COPYPTR(client.array.i.buffer);
1134 SLC_COPYPTR(client.array.n.buffer);
1135 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
1136 {
1137 SLC_COPYPTR(client.array.t[i].buffer);
1138 }
1139# ifdef CR_NV_vertex_program
1140 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
1141 {
1142 SLC_COPYPTR(client.array.a[i].buffer);
1143 }
1144# endif
1145#endif /*CR_ARB_vertex_buffer_object*/
1146
1147 /*@todo CR_NV_vertex_program*/
1148 crStateCopyEvalPtrs1D(pTmpContext->eval.eval1D, pContext->eval.eval1D);
1149 crStateCopyEvalPtrs2D(pTmpContext->eval.eval2D, pContext->eval.eval2D);
1150
1151 SLC_COPYPTR(feedback.buffer); /*@todo*/
1152 SLC_COPYPTR(selection.buffer); /*@todo*/
1153
1154 SLC_COPYPTR(lighting.light);
1155
1156 /*This one could be tricky if we're loading snapshot on host with different GPU*/
1157 SLC_COPYPTR(limits.extensions);
1158
1159#if CR_ARB_occlusion_query
1160 SLC_COPYPTR(occlusion.objects); /*@todo*/
1161#endif
1162
1163 SLC_COPYPTR(program.errorString);
1164 SLC_COPYPTR(program.programHash);
1165 SLC_COPYPTR(program.defaultVertexProgram);
1166 SLC_COPYPTR(program.defaultFragmentProgram);
1167
1168 /* Texture pointers */
1169 for (i=0; i<6; ++i)
1170 {
1171 SLC_COPYPTR(texture.base1D.level[i]);
1172 SLC_COPYPTR(texture.base2D.level[i]);
1173 SLC_COPYPTR(texture.base3D.level[i]);
1174 SLC_COPYPTR(texture.proxy1D.level[i]);
1175 SLC_COPYPTR(texture.proxy2D.level[i]);
1176 SLC_COPYPTR(texture.proxy3D.level[i]);
1177#ifdef CR_ARB_texture_cube_map
1178 SLC_COPYPTR(texture.baseCubeMap.level[i]);
1179 SLC_COPYPTR(texture.proxyCubeMap.level[i]);
1180#endif
1181#ifdef CR_NV_texture_rectangle
1182 SLC_COPYPTR(texture.baseRect.level[i]);
1183 SLC_COPYPTR(texture.proxyRect.level[i]);
1184#endif
1185 }
1186
1187 /* Load transform state */
1188 SLC_COPYPTR(transform.clipPlane);
1189 SLC_COPYPTR(transform.clip);
1190 /* Don't have to worry about pContext->transform.current as it'd be set in crStateSetCurrent call */
1191 /*SLC_COPYPTR(transform.currentStack);*/
1192 SLC_COPYPTR(transform.modelViewStack.stack);
1193 SLC_COPYPTR(transform.projectionStack.stack);
1194 SLC_COPYPTR(transform.colorStack.stack);
1195
1196 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
1197 {
1198 SLC_COPYPTR(transform.textureStack[i].stack);
1199 }
1200 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
1201 {
1202 SLC_COPYPTR(transform.programStack[i].stack);
1203 }
1204
1205#ifdef CR_EXT_framebuffer_object
1206 SLC_COPYPTR(framebufferobject.framebuffers);
1207 SLC_COPYPTR(framebufferobject.renderbuffers);
1208#endif
1209
1210#ifdef CR_OPENGL_VERSION_2_0
1211 SLC_COPYPTR(glsl.shaders);
1212 SLC_COPYPTR(glsl.programs);
1213#endif
1214
1215 /* Have to preserve original context id */
1216 CRASSERT(pTmpContext->id == pContext->id);
1217 /* Copy ordinary state to real context */
1218 crMemcpy(pContext, pTmpContext, sizeof(*pTmpContext));
1219 crFree(pTmpContext);
1220 pTmpContext = NULL;
1221
1222 /* Now deal with pointers */
1223
1224 /* Load transform state */
1225 rc = SSMR3GetMem(pSSM, pContext->transform.clipPlane, sizeof(GLvectord)*CR_MAX_CLIP_PLANES);
1226 AssertRCReturn(rc, rc);
1227 rc = SSMR3GetMem(pSSM, pContext->transform.clip, sizeof(GLboolean)*CR_MAX_CLIP_PLANES);
1228 AssertRCReturn(rc, rc);
1229 rc = crStateLoadMatrixStack(&pContext->transform.modelViewStack, pSSM);
1230 AssertRCReturn(rc, rc);
1231 rc = crStateLoadMatrixStack(&pContext->transform.projectionStack, pSSM);
1232 AssertRCReturn(rc, rc);
1233 rc = crStateLoadMatrixStack(&pContext->transform.colorStack, pSSM);
1234 AssertRCReturn(rc, rc);
1235 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
1236 {
1237 rc = crStateLoadMatrixStack(&pContext->transform.textureStack[i], pSSM);
1238 AssertRCReturn(rc, rc);
1239 }
1240 for (i = 0 ; i < CR_MAX_PROGRAM_MATRICES ; i++)
1241 {
1242 rc = crStateLoadMatrixStack(&pContext->transform.programStack[i], pSSM);
1243 AssertRCReturn(rc, rc);
1244 }
1245
1246 /* Load Textures */
1247 rc = crStateLoadTextureObjData(&pContext->texture.base1D, pSSM);
1248 AssertRCReturn(rc, rc);
1249 rc = crStateLoadTextureObjData(&pContext->texture.base2D, pSSM);
1250 AssertRCReturn(rc, rc);
1251 rc = crStateLoadTextureObjData(&pContext->texture.base3D, pSSM);
1252 AssertRCReturn(rc, rc);
1253 rc = crStateLoadTextureObjData(&pContext->texture.proxy1D, pSSM);
1254 AssertRCReturn(rc, rc);
1255 rc = crStateLoadTextureObjData(&pContext->texture.proxy2D, pSSM);
1256 AssertRCReturn(rc, rc);
1257 rc = crStateLoadTextureObjData(&pContext->texture.proxy3D, pSSM);
1258 AssertRCReturn(rc, rc);
1259#ifdef CR_ARB_texture_cube_map
1260 rc = crStateLoadTextureObjData(&pContext->texture.baseCubeMap, pSSM);
1261 AssertRCReturn(rc, rc);
1262 rc = crStateLoadTextureObjData(&pContext->texture.proxyCubeMap, pSSM);
1263 AssertRCReturn(rc, rc);
1264#endif
1265#ifdef CR_NV_texture_rectangle
1266 rc = crStateLoadTextureObjData(&pContext->texture.baseRect, pSSM);
1267 AssertRCReturn(rc, rc);
1268 rc = crStateLoadTextureObjData(&pContext->texture.proxyRect, pSSM);
1269 AssertRCReturn(rc, rc);
1270#endif
1271
1272 /* Load shared textures */
1273 CRASSERT(pContext->shared && pContext->shared->textureTable);
1274 rc = SSMR3GetU32(pSSM, &uiNumElems);
1275 AssertRCReturn(rc, rc);
1276 for (ui=0; ui<uiNumElems; ++ui)
1277 {
1278 CRTextureObj *pTexture;
1279
1280 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
1281 AssertRCReturn(rc, rc);
1282
1283 pTexture = (CRTextureObj *) crCalloc(sizeof(CRTextureObj));
1284 if (!pTexture) return VERR_NO_MEMORY;
1285
1286 rc = SSMR3GetMem(pSSM, pTexture, sizeof(*pTexture));
1287 AssertRCReturn(rc, rc);
1288
1289 //DIRTY(pTexture->dirty, pContext->neg_bitid);
1290 //DIRTY(pTexture->imageBit, pContext->neg_bitid);
1291
1292 /*allocate actual memory*/
1293 for (i=0; i<6; ++i) {
1294 pTexture->level[i] = (CRTextureLevel *) crCalloc(sizeof(CRTextureLevel) * MAX_MIPMAP_LEVELS);
1295 if (!pTexture->level[i]) return VERR_NO_MEMORY;
1296 }
1297
1298 rc = crStateLoadTextureObjData(pTexture, pSSM);
1299 AssertRCReturn(rc, rc);
1300
1301 crHashtableAdd(pContext->shared->textureTable, key, pTexture);
1302 }
1303
1304 /* Load current texture pointers */
1305 for (i=0; i<CR_MAX_TEXTURE_UNITS; ++i)
1306 {
1307 rc = crStateLoadTexUnitCurrentTexturePtrs(&pContext->texture.unit[i], pContext, pSSM);
1308 AssertRCReturn(rc, rc);
1309 }
1310 //FILLDIRTY(GetCurrentBits()->texture.dirty);
1311
1312 /* Mark textures for resending to GPU */
1313 pContext->texture.bResyncNeeded = GL_TRUE;
1314
1315 /* Load lights */
1316 CRASSERT(pContext->lighting.light);
1317 rc = SSMR3GetMem(pSSM, pContext->lighting.light, CR_MAX_LIGHTS * sizeof(*pContext->lighting.light));
1318 AssertRCReturn(rc, rc);
1319
1320 /* Load attrib stack*/
1321 for ( i = 0 ; i < CR_MAX_ATTRIB_STACK_DEPTH ; i++)
1322 {
1323 if (pContext->attrib.enableStack[i].clip)
1324 {
1325 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.enableStack[i].clip,
1326 pContext->limits.maxClipPlanes*sizeof(GLboolean));
1327 AssertRCReturn(rc, rc);
1328 }
1329
1330 if (pContext->attrib.enableStack[i].light)
1331 {
1332 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.enableStack[i].light,
1333 pContext->limits.maxLights*sizeof(GLboolean));
1334 AssertRCReturn(rc, rc);
1335 }
1336
1337 if (pContext->attrib.lightingStack[i].light)
1338 {
1339 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.lightingStack[i].light,
1340 pContext->limits.maxLights*sizeof(CRLight));
1341 AssertRCReturn(rc, rc);
1342 }
1343
1344 for (k=0; k<pContext->limits.maxTextureUnits; ++k)
1345 {
1346 rc = crStateLoadTexUnitCurrentTexturePtrs(&pContext->attrib.textureStack[i].unit[k], pContext, pSSM);
1347 AssertRCReturn(rc, rc);
1348 }
1349
1350 if (pContext->attrib.transformStack[i].clip)
1351 {
1352 rc = crStateAllocAndSSMR3GetMem(pSSM, (void*)&pContext->attrib.transformStack[i].clip,
1353 pContext->limits.maxClipPlanes*sizeof(GLboolean));
1354 AssertRCReturn(rc, rc);
1355 }
1356
1357 if (pContext->attrib.transformStack[i].clipPlane)
1358 {
1359 rc = crStateAllocAndSSMR3GetMem(pSSM, (void**)&pContext->attrib.transformStack[i].clipPlane,
1360 pContext->limits.maxClipPlanes*sizeof(GLvectord));
1361 AssertRCReturn(rc, rc);
1362 }
1363 rc = crSateLoadEvalCoeffs1D(pContext->attrib.evalStack[i].eval1D, GL_TRUE, pSSM);
1364 AssertRCReturn(rc, rc);
1365 rc = crSateLoadEvalCoeffs2D(pContext->attrib.evalStack[i].eval2D, GL_TRUE, pSSM);
1366 AssertRCReturn(rc, rc);
1367 }
1368
1369 /* Load evaluator coeffs */
1370 rc = crSateLoadEvalCoeffs1D(pContext->eval.eval1D, GL_FALSE, pSSM);
1371 AssertRCReturn(rc, rc);
1372 rc = crSateLoadEvalCoeffs2D(pContext->eval.eval2D, GL_FALSE, pSSM);
1373 AssertRCReturn(rc, rc);
1374
1375 /* Load buffer objects */
1376#ifdef CR_ARB_vertex_buffer_object
1377 rc = SSMR3GetU32(pSSM, &uiNumElems);
1378 AssertRCReturn(rc, rc);
1379 for (ui=0; ui<=uiNumElems; ++ui) /*ui<=uiNumElems to load nullBuffer in same loop*/
1380 {
1381 CRBufferObject *pBufferObj;
1382
1383 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
1384 AssertRCReturn(rc, rc);
1385
1386 /* default one should be already allocated */
1387 if (key==0)
1388 {
1389 pBufferObj = pContext->bufferobject.nullBuffer;
1390 if (!pBufferObj) return VERR_SSM_UNEXPECTED_DATA;
1391 }
1392 else
1393 {
1394 pBufferObj = (CRBufferObject *) crCalloc(sizeof(*pBufferObj));
1395 if (!pBufferObj) return VERR_NO_MEMORY;
1396 }
1397
1398 rc = SSMR3GetMem(pSSM, pBufferObj, sizeof(*pBufferObj));
1399 AssertRCReturn(rc, rc);
1400
1401 if (pBufferObj->data)
1402 {
1403 CRASSERT(pBufferObj->size>0);
1404 pBufferObj->data = crAlloc(pBufferObj->size);
1405 rc = SSMR3GetMem(pSSM, pBufferObj->data, pBufferObj->size);
1406 AssertRCReturn(rc, rc);
1407
1408 //DIRTY(pBufferObj->dirty, pContext->neg_bitid);
1409 //pBufferObj->dirtyStart = 0;
1410 //pBufferObj->dirtyLength = pBufferObj->size;
1411 }
1412 else if (pBufferObj->name!=0 && pBufferObj->size>0)
1413 {
1414 rc = SSMR3GetMem(pSSM, &pBufferObj->data, sizeof(pBufferObj->data));
1415 AssertRCReturn(rc, rc);
1416
1417 if (pBufferObj->data)
1418 {
1419 pBufferObj->data = crAlloc(pBufferObj->size);
1420 rc = SSMR3GetMem(pSSM, pBufferObj->data, pBufferObj->size);
1421 AssertRCReturn(rc, rc);
1422 }
1423 }
1424
1425
1426 if (key!=0)
1427 crHashtableAdd(pContext->bufferobject.buffers, key, pBufferObj);
1428 }
1429 //FILLDIRTY(GetCurrentBits()->bufferobject.dirty);
1430 /* Load pointers */
1431#define CRS_GET_BO(name) (((name)==0) ? (pContext->bufferobject.nullBuffer) : crHashtableSearch(pContext->bufferobject.buffers, name))
1432 rc = SSMR3GetU32(pSSM, &ui);
1433 AssertRCReturn(rc, rc);
1434 pContext->bufferobject.arrayBuffer = CRS_GET_BO(ui);
1435 rc = SSMR3GetU32(pSSM, &ui);
1436 AssertRCReturn(rc, rc);
1437 pContext->bufferobject.elementsBuffer = CRS_GET_BO(ui);
1438
1439 /* Load bound array buffers*/
1440 rc = SSMR3GetU32(pSSM, &ui);
1441 AssertRCReturn(rc, rc);
1442 pContext->client.array.v.buffer = CRS_GET_BO(ui);
1443
1444 rc = SSMR3GetU32(pSSM, &ui);
1445 AssertRCReturn(rc, rc);
1446 pContext->client.array.c.buffer = CRS_GET_BO(ui);
1447
1448 rc = SSMR3GetU32(pSSM, &ui);
1449 AssertRCReturn(rc, rc);
1450 pContext->client.array.f.buffer = CRS_GET_BO(ui);
1451
1452 rc = SSMR3GetU32(pSSM, &ui);
1453 AssertRCReturn(rc, rc);
1454 pContext->client.array.s.buffer = CRS_GET_BO(ui);
1455
1456 rc = SSMR3GetU32(pSSM, &ui);
1457 AssertRCReturn(rc, rc);
1458 pContext->client.array.e.buffer = CRS_GET_BO(ui);
1459
1460 rc = SSMR3GetU32(pSSM, &ui);
1461 AssertRCReturn(rc, rc);
1462 pContext->client.array.i.buffer = CRS_GET_BO(ui);
1463
1464 rc = SSMR3GetU32(pSSM, &ui);
1465 AssertRCReturn(rc, rc);
1466 pContext->client.array.n.buffer = CRS_GET_BO(ui);
1467
1468 for (i = 0; i < CR_MAX_TEXTURE_UNITS; i++)
1469 {
1470 rc = SSMR3GetU32(pSSM, &ui);
1471 AssertRCReturn(rc, rc);
1472 pContext->client.array.t[i].buffer = CRS_GET_BO(ui);
1473 }
1474# ifdef CR_NV_vertex_program
1475 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
1476 {
1477 rc = SSMR3GetU32(pSSM, &ui);
1478 AssertRCReturn(rc, rc);
1479 pContext->client.array.a[i].buffer = CRS_GET_BO(ui);
1480 }
1481# endif
1482#undef CRS_GET_BO
1483
1484 pContext->bufferobject.bResyncNeeded = GL_TRUE;
1485#endif
1486
1487 /* Load pixel/vertex programs */
1488 rc = SSMR3GetU32(pSSM, &uiNumElems);
1489 AssertRCReturn(rc, rc);
1490 /* Load defauls programs */
1491 rc = crStateLoadProgram(&pContext->program.defaultVertexProgram, pSSM);
1492 AssertRCReturn(rc, rc);
1493 //FILLDIRTY(pContext->program.defaultVertexProgram->dirtyProgram);
1494 rc = crStateLoadProgram(&pContext->program.defaultFragmentProgram, pSSM);
1495 AssertRCReturn(rc, rc);
1496 //FILLDIRTY(pContext->program.defaultFragmentProgram->dirtyProgram);
1497 /* Load all the rest */
1498 for (ui=0; ui<uiNumElems; ++ui)
1499 {
1500 CRProgram *pProgram = NULL;
1501 rc = crStateLoadProgram(&pProgram, pSSM);
1502 AssertRCReturn(rc, rc);
1503 crHashtableAdd(pContext->program.programHash, pProgram->id, pProgram);
1504 //DIRTY(pProgram->dirtyProgram, pContext->neg_bitid);
1505
1506 }
1507 //FILLDIRTY(GetCurrentBits()->program.dirty);
1508 /* Load Pointers */
1509 rc = SSMR3GetU32(pSSM, &ui);
1510 AssertRCReturn(rc, rc);
1511 pContext->program.currentVertexProgram = ui==0 ? pContext->program.defaultVertexProgram
1512 : crHashtableSearch(pContext->program.programHash, ui);
1513 rc = SSMR3GetU32(pSSM, &ui);
1514 AssertRCReturn(rc, rc);
1515 pContext->program.currentFragmentProgram = ui==0 ? pContext->program.defaultFragmentProgram
1516 : crHashtableSearch(pContext->program.programHash, ui);
1517
1518 /* Mark programs for resending to GPU */
1519 pContext->program.bResyncNeeded = GL_TRUE;
1520
1521#ifdef CR_EXT_framebuffer_object
1522 /* Load FBOs */
1523 rc = SSMR3GetU32(pSSM, &uiNumElems);
1524 AssertRCReturn(rc, rc);
1525 for (ui=0; ui<uiNumElems; ++ui)
1526 {
1527 CRFramebufferObject *pFBO;
1528 pFBO = crAlloc(sizeof(*pFBO));
1529 if (!pFBO) return VERR_NO_MEMORY;
1530
1531 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
1532 AssertRCReturn(rc, rc);
1533
1534 rc = SSMR3GetMem(pSSM, pFBO, sizeof(*pFBO));
1535 AssertRCReturn(rc, rc);
1536
1537 crHashtableAdd(pContext->framebufferobject.framebuffers, key, pFBO);
1538 }
1539
1540 rc = SSMR3GetU32(pSSM, &uiNumElems);
1541 AssertRCReturn(rc, rc);
1542 for (ui=0; ui<uiNumElems; ++ui)
1543 {
1544 CRRenderbufferObject *pRBO;
1545 pRBO = crAlloc(sizeof(*pRBO));
1546 if (!pRBO) return VERR_NO_MEMORY;
1547
1548 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
1549 AssertRCReturn(rc, rc);
1550
1551 rc = SSMR3GetMem(pSSM, pRBO, sizeof(*pRBO));
1552 AssertRCReturn(rc, rc);
1553
1554 crHashtableAdd(pContext->framebufferobject.renderbuffers, key, pRBO);
1555 }
1556
1557 rc = SSMR3GetU32(pSSM, &ui);
1558 AssertRCReturn(rc, rc);
1559 pContext->framebufferobject.drawFB = ui==0 ? NULL
1560 : crHashtableSearch(pContext->framebufferobject.framebuffers, ui);
1561
1562 rc = SSMR3GetU32(pSSM, &ui);
1563 AssertRCReturn(rc, rc);
1564 pContext->framebufferobject.readFB = ui==0 ? NULL
1565 : crHashtableSearch(pContext->framebufferobject.framebuffers, ui);
1566
1567 rc = SSMR3GetU32(pSSM, &ui);
1568 AssertRCReturn(rc, rc);
1569 pContext->framebufferobject.renderbuffer = ui==0 ? NULL
1570 : crHashtableSearch(pContext->framebufferobject.renderbuffers, ui);
1571
1572 /* Mark FBOs/RBOs for resending to GPU */
1573 pContext->framebufferobject.bResyncNeeded = GL_TRUE;
1574#endif
1575
1576#ifdef CR_OPENGL_VERSION_2_0
1577 /* Load GLSL related info */
1578 rc = SSMR3GetU32(pSSM, &uiNumElems);
1579 AssertRCReturn(rc, rc);
1580
1581 for (ui=0; ui<uiNumElems; ++ui)
1582 {
1583 CRGLSLShader *pShader = crStateLoadGLSLShader(pSSM);
1584 if (!pShader) return VERR_SSM_UNEXPECTED_DATA;
1585 crHashtableAdd(pContext->glsl.shaders, pShader->id, pShader);
1586 }
1587
1588 rc = SSMR3GetU32(pSSM, &uiNumElems);
1589 AssertRCReturn(rc, rc);
1590
1591 for (ui=0; ui<uiNumElems; ++ui)
1592 {
1593 CRGLSLProgram *pProgram;
1594 uint32_t numShaders;
1595
1596 pProgram = crAlloc(sizeof(*pProgram));
1597 if (!pProgram) return VERR_NO_MEMORY;
1598
1599 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
1600 AssertRCReturn(rc, rc);
1601
1602 rc = SSMR3GetMem(pSSM, pProgram, sizeof(*pProgram));
1603 AssertRCReturn(rc, rc);
1604
1605 crHashtableAdd(pContext->glsl.programs, key, pProgram);
1606
1607 pProgram->currentState.attachedShaders = crAllocHashtable();
1608
1609 rc = SSMR3GetU32(pSSM, &numShaders);
1610 AssertRCReturn(rc, rc);
1611
1612 for (k=0; k<numShaders; ++k)
1613 {
1614 rc = SSMR3GetMem(pSSM, &key, sizeof(key));
1615 AssertRCReturn(rc, rc);
1616 crHashtableAdd(pProgram->currentState.attachedShaders, key, crHashtableSearch(pContext->glsl.shaders, key));
1617 }
1618
1619 if (pProgram->activeState.attachedShaders)
1620 {
1621 pProgram->activeState.attachedShaders = crAllocHashtable();
1622
1623 rc = SSMR3GetU32(pSSM, &numShaders);
1624 AssertRCReturn(rc, rc);
1625
1626 for (k=0; k<numShaders; ++k)
1627 {
1628 CRGLSLShader *pShader = crStateLoadGLSLShader(pSSM);
1629 if (!pShader) return VERR_SSM_UNEXPECTED_DATA;
1630 crHashtableAdd(pProgram->activeState.attachedShaders, pShader->id, pShader);
1631 }
1632 }
1633
1634 if (pProgram->currentState.cAttribs)
1635 pProgram->currentState.pAttribs = (CRGLSLAttrib*) crAlloc(pProgram->currentState.cAttribs*sizeof(CRGLSLAttrib));
1636 for (k=0; k<pProgram->currentState.cAttribs; ++k)
1637 {
1638 rc = SSMR3GetMem(pSSM, &pProgram->currentState.pAttribs[k].index, sizeof(pProgram->currentState.pAttribs[k].index));
1639 AssertRCReturn(rc, rc);
1640 pProgram->currentState.pAttribs[k].name = crStateLoadString(pSSM);
1641 }
1642
1643 if (pProgram->activeState.cAttribs)
1644 pProgram->activeState.pAttribs = (CRGLSLAttrib*) crAlloc(pProgram->activeState.cAttribs*sizeof(CRGLSLAttrib));
1645 for (k=0; k<pProgram->activeState.cAttribs; ++k)
1646 {
1647 rc = SSMR3GetMem(pSSM, &pProgram->activeState.pAttribs[k].index, sizeof(pProgram->activeState.pAttribs[k].index));
1648 AssertRCReturn(rc, rc);
1649 pProgram->activeState.pAttribs[k].name = crStateLoadString(pSSM);
1650 }
1651
1652 {
1653 int32_t cUniforms;
1654 rc = SSMR3GetS32(pSSM, &cUniforms);
1655 pProgram->cUniforms = cUniforms;
1656 AssertRCReturn(rc, rc);
1657 }
1658
1659 if (pProgram->cUniforms)
1660 {
1661 pProgram->pUniforms = crAlloc(pProgram->cUniforms*sizeof(CRGLSLUniform));
1662 if (!pProgram) return VERR_NO_MEMORY;
1663
1664 for (k=0; k<pProgram->cUniforms; ++k)
1665 {
1666 size_t itemsize, datasize;
1667
1668 rc = SSMR3GetMem(pSSM, &pProgram->pUniforms[k].type, sizeof(GLenum));
1669 pProgram->pUniforms[k].name = crStateLoadString(pSSM);
1670
1671 if (crStateIsIntUniform(pProgram->pUniforms[k].type))
1672 {
1673 itemsize = sizeof(GLint);
1674 } else itemsize = sizeof(GLfloat);
1675
1676 datasize = crStateGetUniformSize(pProgram->pUniforms[k].type)*itemsize;
1677 pProgram->pUniforms[k].data = crAlloc(datasize);
1678 if (!pProgram->pUniforms[k].data) return VERR_NO_MEMORY;
1679
1680 rc = SSMR3GetMem(pSSM, pProgram->pUniforms[k].data, datasize);
1681 }
1682 }
1683 }
1684
1685 rc = SSMR3GetU32(pSSM, &ui);
1686 AssertRCReturn(rc, rc);
1687 pContext->glsl.activeProgram = ui==0 ? NULL
1688 : crHashtableSearch(pContext->glsl.programs, ui);
1689
1690 /*Mark for resending to GPU*/
1691 pContext->glsl.bResyncNeeded = GL_TRUE;
1692#endif
1693
1694 return VINF_SUCCESS;
1695}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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