VirtualBox

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

Last change on this file since 27159 was 27091, checked in by vboxsync, 15 years ago

crOpenGL: add GL_ARB_pixel_buffer_object support

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