VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-savedstate.cpp@ 65381

Last change on this file since 65381 was 65381, checked in by vboxsync, 8 years ago

bugref:8282: Additions/linux: submit DRM driver to the Linux kernel: move all graphics device-related header files to a separate sub-directory and add that to the include path where they are needed. The intention is too be able to remove the VBox/ include folder in the DRM driver package.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 37.6 KB
Line 
1/* $Id: DevVGA-SVGA3d-savedstate.cpp 65381 2017-01-20 09:23:53Z vboxsync $ */
2/** @file
3 * DevSVGA3d - VMWare SVGA device, 3D parts - Saved state and assocated stuff.
4 */
5
6/*
7 * Copyright (C) 2013-2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DEV_VMSVGA
23#include <VBox/vmm/pdmdev.h>
24#include <VBox/err.h>
25#include <VBox/log.h>
26
27#include <iprt/assert.h>
28#include <iprt/mem.h>
29
30#include <VBox/vmm/pgm.h> /* required by DevVGA.h */
31#include <VBoxVideo.h> /* required by DevVGA.h */
32
33/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
34#include "DevVGA.h"
35
36#include "DevVGA-SVGA.h"
37#include "DevVGA-SVGA3d.h"
38#define VMSVGA3D_INCL_STRUCTURE_DESCRIPTORS
39#include "DevVGA-SVGA3d-internal.h"
40
41
42
43/**
44 * Reinitializes an active context.
45 *
46 * @returns VBox status code.
47 * @param pThis The VMSVGA device state.
48 * @param pContext The freshly loaded context to reinitialize.
49 */
50static int vmsvga3dLoadReinitContext(PVGASTATE pThis, PVMSVGA3DCONTEXT pContext)
51{
52 int rc;
53 uint32_t cid = pContext->id;
54 Assert(cid != SVGA3D_INVALID_ID);
55
56 /* First set the render targets as they change the internal state (reset viewport etc) */
57 Log(("vmsvga3dLoadReinitContext: Recreate render targets BEGIN [cid=%#x]\n", cid));
58 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aRenderTargets); j++)
59 {
60 if (pContext->state.aRenderTargets[j] != SVGA3D_INVALID_ID)
61 {
62 SVGA3dSurfaceImageId target;
63
64 target.sid = pContext->state.aRenderTargets[j];
65 target.face = 0;
66 target.mipmap = 0;
67 rc = vmsvga3dSetRenderTarget(pThis, cid, (SVGA3dRenderTargetType)j, target);
68 AssertRCReturn(rc, rc);
69 }
70 }
71 Log(("vmsvga3dLoadReinitContext: Recreate render targets END\n"));
72
73 /* Recreate the render state */
74 Log(("vmsvga3dLoadReinitContext: Recreate render state BEGIN\n"));
75 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aRenderState); j++)
76 {
77 SVGA3dRenderState *pRenderState = &pContext->state.aRenderState[j];
78
79 if (pRenderState->state != SVGA3D_RS_INVALID)
80 vmsvga3dSetRenderState(pThis, pContext->id, 1, pRenderState);
81 }
82 Log(("vmsvga3dLoadReinitContext: Recreate render state END\n"));
83
84 /* Recreate the texture state */
85 Log(("vmsvga3dLoadReinitContext: Recreate texture state BEGIN\n"));
86 for (uint32_t iStage = 0; iStage < SVGA3D_MAX_TEXTURE_STAGE; iStage++)
87 {
88 for (uint32_t j = 0; j < SVGA3D_TS_MAX; j++)
89 {
90 SVGA3dTextureState *pTextureState = &pContext->state.aTextureState[iStage][j];
91
92 if (pTextureState->name != SVGA3D_TS_INVALID)
93 vmsvga3dSetTextureState(pThis, pContext->id, 1, pTextureState);
94 }
95 }
96 Log(("vmsvga3dLoadReinitContext: Recreate texture state END\n"));
97
98 /* Reprogram the clip planes. */
99 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aClipPlane); j++)
100 {
101 if (pContext->state.aClipPlane[j].fValid == true)
102 vmsvga3dSetClipPlane(pThis, cid, j, pContext->state.aClipPlane[j].plane);
103 }
104
105 /* Reprogram the light data. */
106 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aLightData); j++)
107 {
108 if (pContext->state.aLightData[j].fValidData == true)
109 vmsvga3dSetLightData(pThis, cid, j, &pContext->state.aLightData[j].data);
110 if (pContext->state.aLightData[j].fEnabled)
111 vmsvga3dSetLightEnabled(pThis, cid, j, true);
112 }
113
114 /* Recreate the transform state. */
115 if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_TRANSFORM)
116 {
117 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTransformState); j++)
118 {
119 if (pContext->state.aTransformState[j].fValid == true)
120 vmsvga3dSetTransform(pThis, cid, (SVGA3dTransformType)j, pContext->state.aTransformState[j].matrix);
121 }
122 }
123
124 /* Reprogram the material data. */
125 if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_MATERIAL)
126 {
127 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aMaterial); j++)
128 {
129 if (pContext->state.aMaterial[j].fValid == true)
130 vmsvga3dSetMaterial(pThis, cid, (SVGA3dFace)j, &pContext->state.aMaterial[j].material);
131 }
132 }
133
134 if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_SCISSORRECT)
135 vmsvga3dSetScissorRect(pThis, cid, &pContext->state.RectScissor);
136 if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_ZRANGE)
137 vmsvga3dSetZRange(pThis, cid, pContext->state.zRange);
138 if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_VIEWPORT)
139 vmsvga3dSetViewPort(pThis, cid, &pContext->state.RectViewPort);
140 if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_VERTEXSHADER)
141 vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_VS, pContext->state.shidVertex);
142 if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_PIXELSHADER)
143 vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_PS, pContext->state.shidPixel);
144
145 Log(("vmsvga3dLoadReinitContext: returns [cid=%#x]\n", cid));
146 return VINF_SUCCESS;
147}
148
149int vmsvga3dLoadExec(PVGASTATE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
150{
151 RT_NOREF(uVersion, uPass);
152 PVMSVGA3DSTATE pState = pThis->svga.p3dState;
153 AssertReturn(pState, VERR_NO_MEMORY);
154 int rc;
155 uint32_t cContexts, cSurfaces;
156 LogFlow(("vmsvga3dLoadExec:\n"));
157
158#ifndef RT_OS_DARWIN /** @todo r=bird: this is normally done on the EMT, so for DARWIN we do that when loading saved state too now. See DevVGA-SVGA.cpp */
159 /* Must initialize now as the recreation calls below rely on an initialized 3d subsystem. */
160 vmsvga3dPowerOn(pThis);
161#endif
162
163 /* Get the generic 3d state first. */
164 rc = SSMR3GetStructEx(pSSM, pState, sizeof(*pState), 0, g_aVMSVGA3DSTATEFields, NULL);
165 AssertRCReturn(rc, rc);
166
167 cContexts = pState->cContexts;
168 cSurfaces = pState->cSurfaces;
169 pState->cContexts = 0;
170 pState->cSurfaces = 0;
171
172 /* Fetch all active contexts. */
173 for (uint32_t i = 0; i < cContexts; i++)
174 {
175 PVMSVGA3DCONTEXT pContext;
176 uint32_t cid;
177
178 /* Get the context id */
179 rc = SSMR3GetU32(pSSM, &cid);
180 AssertRCReturn(rc, rc);
181
182 if (cid != SVGA3D_INVALID_ID)
183 {
184 uint32_t cPixelShaderConst, cVertexShaderConst, cPixelShaders, cVertexShaders;
185 LogFlow(("vmsvga3dLoadExec: Loading cid=%#x\n", cid));
186
187#ifdef VMSVGA3D_OPENGL
188 if (cid == VMSVGA3D_SHARED_CTX_ID)
189 {
190 i--; /* Not included in cContexts. */
191 pContext = &pState->SharedCtx;
192 if (pContext->id != VMSVGA3D_SHARED_CTX_ID)
193 {
194 rc = vmsvga3dContextDefineOgl(pThis, VMSVGA3D_SHARED_CTX_ID, VMSVGA3D_DEF_CTX_F_SHARED_CTX);
195 AssertRCReturn(rc, rc);
196 }
197 }
198 else
199#endif
200 {
201 rc = vmsvga3dContextDefine(pThis, cid);
202 AssertRCReturn(rc, rc);
203
204 pContext = pState->papContexts[i];
205 }
206 AssertReturn(pContext->id == cid, VERR_INTERNAL_ERROR);
207
208 rc = SSMR3GetStructEx(pSSM, pContext, sizeof(*pContext), 0, g_aVMSVGA3DCONTEXTFields, NULL);
209 AssertRCReturn(rc, rc);
210
211 cPixelShaders = pContext->cPixelShaders;
212 cVertexShaders = pContext->cVertexShaders;
213 cPixelShaderConst = pContext->state.cPixelShaderConst;
214 cVertexShaderConst = pContext->state.cVertexShaderConst;
215 pContext->cPixelShaders = 0;
216 pContext->cVertexShaders = 0;
217 pContext->state.cPixelShaderConst = 0;
218 pContext->state.cVertexShaderConst = 0;
219
220 /* Fetch all pixel shaders. */
221 for (uint32_t j = 0; j < cPixelShaders; j++)
222 {
223 VMSVGA3DSHADER shader;
224 uint32_t shid;
225
226 /* Fetch the id first. */
227 rc = SSMR3GetU32(pSSM, &shid);
228 AssertRCReturn(rc, rc);
229
230 if (shid != SVGA3D_INVALID_ID)
231 {
232 uint32_t *pData;
233
234 /* Fetch a copy of the shader struct. */
235 rc = SSMR3GetStructEx(pSSM, &shader, sizeof(shader), 0, g_aVMSVGA3DSHADERFields, NULL);
236 AssertRCReturn(rc, rc);
237
238 pData = (uint32_t *)RTMemAlloc(shader.cbData);
239 AssertReturn(pData, VERR_NO_MEMORY);
240
241 rc = SSMR3GetMem(pSSM, pData, shader.cbData);
242 AssertRCReturn(rc, rc);
243
244 rc = vmsvga3dShaderDefine(pThis, cid, shid, shader.type, shader.cbData, pData);
245 AssertRCReturn(rc, rc);
246
247 RTMemFree(pData);
248 }
249 }
250
251 /* Fetch all vertex shaders. */
252 for (uint32_t j = 0; j < cVertexShaders; j++)
253 {
254 VMSVGA3DSHADER shader;
255 uint32_t shid;
256
257 /* Fetch the id first. */
258 rc = SSMR3GetU32(pSSM, &shid);
259 AssertRCReturn(rc, rc);
260
261 if (shid != SVGA3D_INVALID_ID)
262 {
263 uint32_t *pData;
264
265 /* Fetch a copy of the shader struct. */
266 rc = SSMR3GetStructEx(pSSM, &shader, sizeof(shader), 0, g_aVMSVGA3DSHADERFields, NULL);
267 AssertRCReturn(rc, rc);
268
269 pData = (uint32_t *)RTMemAlloc(shader.cbData);
270 AssertReturn(pData, VERR_NO_MEMORY);
271
272 rc = SSMR3GetMem(pSSM, pData, shader.cbData);
273 AssertRCReturn(rc, rc);
274
275 rc = vmsvga3dShaderDefine(pThis, cid, shid, shader.type, shader.cbData, pData);
276 AssertRCReturn(rc, rc);
277
278 RTMemFree(pData);
279 }
280 }
281
282 /* Fetch pixel shader constants. */
283 for (uint32_t j = 0; j < cPixelShaderConst; j++)
284 {
285 VMSVGASHADERCONST ShaderConst;
286
287 rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
288 AssertRCReturn(rc, rc);
289
290 if (ShaderConst.fValid)
291 {
292 rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_PS, ShaderConst.ctype, 1, ShaderConst.value);
293 AssertRCReturn(rc, rc);
294 }
295 }
296
297 /* Fetch vertex shader constants. */
298 for (uint32_t j = 0; j < cVertexShaderConst; j++)
299 {
300 VMSVGASHADERCONST ShaderConst;
301
302 rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
303 AssertRCReturn(rc, rc);
304
305 if (ShaderConst.fValid)
306 {
307 rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_VS, ShaderConst.ctype, 1, ShaderConst.value);
308 AssertRCReturn(rc, rc);
309 }
310 }
311 }
312 }
313
314#ifdef VMSVGA3D_OPENGL
315 /* Make the shared context the current one. */
316 if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
317 VMSVGA3D_SET_CURRENT_CONTEXT(pState, &pState->SharedCtx);
318#endif
319
320 /* Fetch all surfaces. */
321 for (uint32_t i = 0; i < cSurfaces; i++)
322 {
323 uint32_t sid;
324
325 /* Fetch the id first. */
326 rc = SSMR3GetU32(pSSM, &sid);
327 AssertRCReturn(rc, rc);
328
329 if (sid != SVGA3D_INVALID_ID)
330 {
331 VMSVGA3DSURFACE surface;
332 LogFlow(("vmsvga3dLoadExec: Loading sid=%#x\n", sid));
333
334 /* Fetch the surface structure first. */
335 rc = SSMR3GetStructEx(pSSM, &surface, sizeof(surface), 0, g_aVMSVGA3DSURFACEFields, NULL);
336 AssertRCReturn(rc, rc);
337
338 {
339 uint32_t cMipLevels = surface.faces[0].numMipLevels * surface.cFaces;
340 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = (PVMSVGA3DMIPMAPLEVEL)RTMemAlloc(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL));
341 AssertReturn(pMipmapLevel, VERR_NO_MEMORY);
342 SVGA3dSize *pMipmapLevelSize = (SVGA3dSize *)RTMemAlloc(cMipLevels * sizeof(SVGA3dSize));
343 AssertReturn(pMipmapLevelSize, VERR_NO_MEMORY);
344
345 /* Load the mip map level info. */
346 for (uint32_t face=0; face < surface.cFaces; face++)
347 {
348 for (uint32_t j = 0; j < surface.faces[0].numMipLevels; j++)
349 {
350 uint32_t idx = j + face * surface.faces[0].numMipLevels;
351 /* Load the mip map level struct. */
352 rc = SSMR3GetStructEx(pSSM, &pMipmapLevel[idx], sizeof(pMipmapLevel[idx]), 0, g_aVMSVGA3DMIPMAPLEVELFields, NULL);
353 AssertRCReturn(rc, rc);
354
355 pMipmapLevelSize[idx] = pMipmapLevel[idx].size;
356 }
357 }
358
359 rc = vmsvga3dSurfaceDefine(pThis, sid, surface.flags, surface.format, surface.faces, surface.multiSampleCount, surface.autogenFilter, cMipLevels, pMipmapLevelSize);
360 AssertRCReturn(rc, rc);
361
362 RTMemFree(pMipmapLevelSize);
363 RTMemFree(pMipmapLevel);
364 }
365
366 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
367 Assert(pSurface->id == sid);
368
369 pSurface->fDirty = false;
370
371 /* Load the mip map level data. */
372 for (uint32_t j = 0; j < pSurface->faces[0].numMipLevels * pSurface->cFaces; j++)
373 {
374 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[j];
375 bool fDataPresent = false;
376
377 Assert(pMipmapLevel->cbSurface);
378 pMipmapLevel->pSurfaceData = RTMemAllocZ(pMipmapLevel->cbSurface);
379 AssertReturn(pMipmapLevel->pSurfaceData, VERR_NO_MEMORY);
380
381 /* Fetch the data present boolean first. */
382 rc = SSMR3GetBool(pSSM, &fDataPresent);
383 AssertRCReturn(rc, rc);
384
385 Log(("Surface sid=%x: load mipmap level %d with %x bytes data (present=%d).\n", sid, j, pMipmapLevel->cbSurface, fDataPresent));
386
387 if (fDataPresent)
388 {
389 rc = SSMR3GetMem(pSSM, pMipmapLevel->pSurfaceData, pMipmapLevel->cbSurface);
390 AssertRCReturn(rc, rc);
391 pMipmapLevel->fDirty = true;
392 pSurface->fDirty = true;
393 }
394 else
395 {
396 pMipmapLevel->fDirty = false;
397 }
398 }
399 }
400 }
401
402#ifdef VMSVGA3D_OPENGL
403 /* Reinitialize the shared context. */
404 LogFlow(("vmsvga3dLoadExec: pState->SharedCtx.id=%#x\n", pState->SharedCtx.id));
405 if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
406 {
407 rc = vmsvga3dLoadReinitContext(pThis, &pState->SharedCtx);
408 AssertRCReturn(rc, rc);
409 }
410#endif
411
412 /* Reinitialize all active contexts. */
413 for (uint32_t i = 0; i < pState->cContexts; i++)
414 {
415 PVMSVGA3DCONTEXT pContext = pState->papContexts[i];
416 if (pContext->id != SVGA3D_INVALID_ID)
417 {
418 rc = vmsvga3dLoadReinitContext(pThis, pContext);
419 AssertRCReturn(rc, rc);
420 }
421 }
422
423 LogFlow(("vmsvga3dLoadExec: return success\n"));
424 return VINF_SUCCESS;
425}
426
427
428static int vmsvga3dSaveContext(PVGASTATE pThis, PSSMHANDLE pSSM, PVMSVGA3DCONTEXT pContext)
429{
430 RT_NOREF(pThis);
431 uint32_t cid = pContext->id;
432
433 /* Save the id first. */
434 int rc = SSMR3PutU32(pSSM, cid);
435 AssertRCReturn(rc, rc);
436
437 if (cid != SVGA3D_INVALID_ID)
438 {
439 /* Save a copy of the context structure first. */
440 rc = SSMR3PutStructEx(pSSM, pContext, sizeof(*pContext), 0, g_aVMSVGA3DCONTEXTFields, NULL);
441 AssertRCReturn(rc, rc);
442
443 /* Save all pixel shaders. */
444 for (uint32_t j = 0; j < pContext->cPixelShaders; j++)
445 {
446 PVMSVGA3DSHADER pShader = &pContext->paPixelShader[j];
447
448 /* Save the id first. */
449 rc = SSMR3PutU32(pSSM, pShader->id);
450 AssertRCReturn(rc, rc);
451
452 if (pShader->id != SVGA3D_INVALID_ID)
453 {
454 uint32_t cbData = pShader->cbData;
455
456 /* Save a copy of the shader struct. */
457 rc = SSMR3PutStructEx(pSSM, pShader, sizeof(*pShader), 0, g_aVMSVGA3DSHADERFields, NULL);
458 AssertRCReturn(rc, rc);
459
460 Log(("Save pixelshader shid=%d with %x bytes code.\n", pShader->id, cbData));
461 rc = SSMR3PutMem(pSSM, pShader->pShaderProgram, cbData);
462 AssertRCReturn(rc, rc);
463 }
464 }
465
466 /* Save all vertex shaders. */
467 for (uint32_t j = 0; j < pContext->cVertexShaders; j++)
468 {
469 PVMSVGA3DSHADER pShader = &pContext->paVertexShader[j];
470
471 /* Save the id first. */
472 rc = SSMR3PutU32(pSSM, pShader->id);
473 AssertRCReturn(rc, rc);
474
475 if (pShader->id != SVGA3D_INVALID_ID)
476 {
477 uint32_t cbData = pShader->cbData;
478
479 /* Save a copy of the shader struct. */
480 rc = SSMR3PutStructEx(pSSM, pShader, sizeof(*pShader), 0, g_aVMSVGA3DSHADERFields, NULL);
481 AssertRCReturn(rc, rc);
482
483 Log(("Save vertex shader shid=%d with %x bytes code.\n", pShader->id, cbData));
484 /* Fetch the shader code and save it. */
485 rc = SSMR3PutMem(pSSM, pShader->pShaderProgram, cbData);
486 AssertRCReturn(rc, rc);
487 }
488 }
489
490 /* Save pixel shader constants. */
491 for (uint32_t j = 0; j < pContext->state.cPixelShaderConst; j++)
492 {
493 rc = SSMR3PutStructEx(pSSM, &pContext->state.paPixelShaderConst[j], sizeof(pContext->state.paPixelShaderConst[j]), 0, g_aVMSVGASHADERCONSTFields, NULL);
494 AssertRCReturn(rc, rc);
495 }
496
497 /* Save vertex shader constants. */
498 for (uint32_t j = 0; j < pContext->state.cVertexShaderConst; j++)
499 {
500 rc = SSMR3PutStructEx(pSSM, &pContext->state.paVertexShaderConst[j], sizeof(pContext->state.paVertexShaderConst[j]), 0, g_aVMSVGASHADERCONSTFields, NULL);
501 AssertRCReturn(rc, rc);
502 }
503 }
504
505 return VINF_SUCCESS;
506}
507
508int vmsvga3dSaveExec(PVGASTATE pThis, PSSMHANDLE pSSM)
509{
510 PVMSVGA3DSTATE pState = pThis->svga.p3dState;
511 AssertReturn(pState, VERR_NO_MEMORY);
512 int rc;
513
514 /* Save a copy of the generic 3d state first. */
515 rc = SSMR3PutStructEx(pSSM, pState, sizeof(*pState), 0, g_aVMSVGA3DSTATEFields, NULL);
516 AssertRCReturn(rc, rc);
517
518#ifdef VMSVGA3D_OPENGL
519 /* Save the shared context. */
520 if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
521 {
522 rc = vmsvga3dSaveContext(pThis, pSSM, &pState->SharedCtx);
523 AssertRCReturn(rc, rc);
524 }
525#endif
526
527 /* Save all active contexts. */
528 for (uint32_t i = 0; i < pState->cContexts; i++)
529 {
530 rc = vmsvga3dSaveContext(pThis, pSSM, pState->papContexts[i]);
531 AssertRCReturn(rc, rc);
532 }
533
534 /* Save all active surfaces. */
535 for (uint32_t sid = 0; sid < pState->cSurfaces; sid++)
536 {
537 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
538
539 /* Save the id first. */
540 rc = SSMR3PutU32(pSSM, pSurface->id);
541 AssertRCReturn(rc, rc);
542
543 if (pSurface->id != SVGA3D_INVALID_ID)
544 {
545 /* Save a copy of the surface structure first. */
546 rc = SSMR3PutStructEx(pSSM, pSurface, sizeof(*pSurface), 0, g_aVMSVGA3DSURFACEFields, NULL);
547 AssertRCReturn(rc, rc);
548
549 /* Save the mip map level info. */
550 for (uint32_t face=0; face < pSurface->cFaces; face++)
551 {
552 for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
553 {
554 uint32_t idx = i + face * pSurface->faces[0].numMipLevels;
555 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[idx];
556
557 /* Save a copy of the mip map level struct. */
558 rc = SSMR3PutStructEx(pSSM, pMipmapLevel, sizeof(*pMipmapLevel), 0, g_aVMSVGA3DMIPMAPLEVELFields, NULL);
559 AssertRCReturn(rc, rc);
560 }
561 }
562
563 /* Save the mip map level data. */
564 for (uint32_t face=0; face < pSurface->cFaces; face++)
565 {
566 for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
567 {
568 uint32_t idx = i + face * pSurface->faces[0].numMipLevels;
569 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[idx];
570
571 Log(("Surface sid=%d: save mipmap level %d with %x bytes data.\n", sid, i, pMipmapLevel->cbSurface));
572
573#ifdef VMSVGA3D_DIRECT3D
574 if (!pSurface->u.pSurface)
575#else
576 if (pSurface->oglId.texture == OPENGL_INVALID_ID)
577#endif
578 {
579 if (pMipmapLevel->fDirty)
580 {
581 /* Data follows */
582 rc = SSMR3PutBool(pSSM, true);
583 AssertRCReturn(rc, rc);
584
585 Assert(pMipmapLevel->cbSurface);
586 rc = SSMR3PutMem(pSSM, pMipmapLevel->pSurfaceData, pMipmapLevel->cbSurface);
587 AssertRCReturn(rc, rc);
588 }
589 else
590 {
591 /* No data follows */
592 rc = SSMR3PutBool(pSSM, false);
593 AssertRCReturn(rc, rc);
594 }
595 }
596 else
597 {
598#ifdef VMSVGA3D_DIRECT3D
599 void *pData;
600 bool fRenderTargetTexture = false;
601 bool fTexture = false;
602 bool fVertex = false;
603 bool fSkipSave = false;
604 HRESULT hr;
605
606 Assert(pMipmapLevel->cbSurface);
607 pData = RTMemAllocZ(pMipmapLevel->cbSurface);
608 AssertReturn(pData, VERR_NO_MEMORY);
609
610 switch (pSurface->flags & (SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP))
611 {
612 case SVGA3D_SURFACE_HINT_DEPTHSTENCIL:
613 case SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE:
614 /** @todo unable to easily fetch depth surface data in d3d 9 */
615 fSkipSave = true;
616 break;
617 case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
618 fRenderTargetTexture = true;
619 /* no break */
620 case SVGA3D_SURFACE_HINT_TEXTURE:
621 fTexture = true;
622 /* no break */
623 case SVGA3D_SURFACE_HINT_RENDERTARGET:
624 {
625 D3DLOCKED_RECT LockedRect;
626
627 if (fTexture)
628 {
629 if (pSurface->bounce.pTexture)
630 {
631 if ( !pSurface->fDirty
632 && fRenderTargetTexture
633 && i == 0 /* only the first time */)
634 {
635 IDirect3DSurface9 *pSrc, *pDest;
636
637 /** @todo stricter checks for associated context */
638 uint32_t cid = pSurface->idAssociatedContext;
639 if ( cid >= pState->cContexts
640 || pState->papContexts[cid]->id != cid)
641 {
642 Log(("vmsvga3dSaveExec invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
643 AssertFailedReturn(VERR_INVALID_PARAMETER);
644 }
645 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
646
647 hr = pSurface->bounce.pTexture->GetSurfaceLevel(i, &pDest);
648 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetSurfaceLevel failed with %x\n", hr), VERR_INTERNAL_ERROR);
649
650 hr = pSurface->u.pTexture->GetSurfaceLevel(i, &pSrc);
651 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetSurfaceLevel failed with %x\n", hr), VERR_INTERNAL_ERROR);
652
653 hr = pContext->pDevice->GetRenderTargetData(pSrc, pDest);
654 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetRenderTargetData failed with %x\n", hr), VERR_INTERNAL_ERROR);
655
656 pSrc->Release();
657 pDest->Release();
658 }
659
660 hr = pSurface->bounce.pTexture->LockRect(i, /* texture level */
661 &LockedRect,
662 NULL,
663 D3DLOCK_READONLY);
664 }
665 else
666 hr = pSurface->u.pTexture->LockRect(i, /* texture level */
667 &LockedRect,
668 NULL,
669 D3DLOCK_READONLY);
670 }
671 else
672 hr = pSurface->u.pSurface->LockRect(&LockedRect,
673 NULL,
674 D3DLOCK_READONLY);
675 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
676
677 /* Copy the data one line at a time in case the internal pitch is different. */
678 for (uint32_t j = 0; j < pMipmapLevel->size.height; j++)
679 {
680 memcpy((uint8_t *)pData + j * pMipmapLevel->cbSurfacePitch, (uint8_t *)LockedRect.pBits + j * LockedRect.Pitch, pMipmapLevel->cbSurfacePitch);
681 }
682
683 if (fTexture)
684 {
685 if (pSurface->bounce.pTexture)
686 {
687 hr = pSurface->bounce.pTexture->UnlockRect(i);
688 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: UnlockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
689 }
690 else
691 hr = pSurface->u.pTexture->UnlockRect(i);
692 }
693 else
694 hr = pSurface->u.pSurface->UnlockRect();
695 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: UnlockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
696 break;
697 }
698
699 case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
700 fVertex = true;
701 /* no break */
702
703 case SVGA3D_SURFACE_HINT_INDEXBUFFER:
704 {
705 uint8_t *pD3DData;
706
707 if (fVertex)
708 hr = pSurface->u.pVertexBuffer->Lock(0, 0, (void **)&pD3DData, D3DLOCK_READONLY);
709 else
710 hr = pSurface->u.pIndexBuffer->Lock(0, 0, (void **)&pD3DData, D3DLOCK_READONLY);
711 AssertMsg(hr == D3D_OK, ("vmsvga3dSaveExec: Lock %s failed with %x\n", (fVertex) ? "vertex" : "index", hr));
712
713 memcpy(pData, pD3DData, pMipmapLevel->cbSurface);
714
715 if (fVertex)
716 hr = pSurface->u.pVertexBuffer->Unlock();
717 else
718 hr = pSurface->u.pIndexBuffer->Unlock();
719 AssertMsg(hr == D3D_OK, ("vmsvga3dSaveExec: Unlock %s failed with %x\n", (fVertex) ? "vertex" : "index", hr));
720 break;
721 }
722
723 default:
724 AssertFailed();
725 break;
726 }
727
728 if (!fSkipSave)
729 {
730 /* Data follows */
731 rc = SSMR3PutBool(pSSM, true);
732 AssertRCReturn(rc, rc);
733
734 /* And write the surface data. */
735 rc = SSMR3PutMem(pSSM, pData, pMipmapLevel->cbSurface);
736 AssertRCReturn(rc, rc);
737 }
738 else
739 {
740 /* No data follows */
741 rc = SSMR3PutBool(pSSM, false);
742 AssertRCReturn(rc, rc);
743 }
744
745 RTMemFree(pData);
746#elif defined(VMSVGA3D_OPENGL)
747 void *pData = NULL;
748
749 PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
750 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
751
752 Assert(pMipmapLevel->cbSurface);
753
754 switch (pSurface->flags & (SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP))
755 {
756 default:
757 AssertFailed();
758 /* no break */
759 case SVGA3D_SURFACE_HINT_DEPTHSTENCIL:
760 case SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE:
761 /** @todo fetch data from the renderbuffer */
762 /* No data follows */
763 rc = SSMR3PutBool(pSSM, false);
764 AssertRCReturn(rc, rc);
765 break;
766
767 case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
768 case SVGA3D_SURFACE_HINT_TEXTURE:
769 case SVGA3D_SURFACE_HINT_RENDERTARGET:
770 {
771 GLint activeTexture;
772
773 pData = RTMemAllocZ(pMipmapLevel->cbSurface);
774 AssertReturn(pData, VERR_NO_MEMORY);
775
776 glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
777 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
778
779 glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
780 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
781
782 /* Set row length and alignment of the output data. */
783 VMSVGAPACKPARAMS SavedParams;
784 vmsvga3dOglSetPackParams(pState, pContext, pSurface, &SavedParams);
785
786 glGetTexImage(GL_TEXTURE_2D,
787 i,
788 pSurface->formatGL,
789 pSurface->typeGL,
790 pData);
791 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
792
793 vmsvga3dOglRestorePackParams(pState, pContext, pSurface, &SavedParams);
794
795 /* Data follows */
796 rc = SSMR3PutBool(pSSM, true);
797 AssertRCReturn(rc, rc);
798
799 /* And write the surface data. */
800 rc = SSMR3PutMem(pSSM, pData, pMipmapLevel->cbSurface);
801 AssertRCReturn(rc, rc);
802
803 /* Restore the old active texture. */
804 glBindTexture(GL_TEXTURE_2D, activeTexture);
805 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
806 break;
807 }
808
809 case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
810 case SVGA3D_SURFACE_HINT_INDEXBUFFER:
811 {
812 uint8_t *pBufferData;
813
814 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer);
815 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
816
817 pBufferData = (uint8_t *)pState->ext.glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
818 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
819 Assert(pBufferData);
820
821 /* Data follows */
822 rc = SSMR3PutBool(pSSM, true);
823 AssertRCReturn(rc, rc);
824
825 /* And write the surface data. */
826 rc = SSMR3PutMem(pSSM, pBufferData, pMipmapLevel->cbSurface);
827 AssertRCReturn(rc, rc);
828
829 pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);
830 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
831
832 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0);
833 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
834
835 }
836 }
837 if (pData)
838 RTMemFree(pData);
839#else
840#error "Unexpected 3d backend"
841#endif
842 }
843 }
844 }
845 }
846 }
847 return VINF_SUCCESS;
848}
849
850int vmsvga3dSaveShaderConst(PVMSVGA3DCONTEXT pContext, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype,
851 uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4)
852{
853 /* Choose a sane upper limit. */
854 AssertReturn(reg < _32K, VERR_INVALID_PARAMETER);
855
856 if (type == SVGA3D_SHADERTYPE_VS)
857 {
858 if (pContext->state.cVertexShaderConst <= reg)
859 {
860 pContext->state.paVertexShaderConst = (PVMSVGASHADERCONST)RTMemRealloc(pContext->state.paVertexShaderConst, sizeof(VMSVGASHADERCONST) * (reg + 1));
861 AssertReturn(pContext->state.paVertexShaderConst, VERR_NO_MEMORY);
862 for (uint32_t i = pContext->state.cVertexShaderConst; i < reg + 1; i++)
863 pContext->state.paVertexShaderConst[i].fValid = false;
864 pContext->state.cVertexShaderConst = reg + 1;
865 }
866
867 pContext->state.paVertexShaderConst[reg].fValid = true;
868 pContext->state.paVertexShaderConst[reg].ctype = ctype;
869 pContext->state.paVertexShaderConst[reg].value[0] = val1;
870 pContext->state.paVertexShaderConst[reg].value[1] = val2;
871 pContext->state.paVertexShaderConst[reg].value[2] = val3;
872 pContext->state.paVertexShaderConst[reg].value[3] = val4;
873 }
874 else
875 {
876 Assert(type == SVGA3D_SHADERTYPE_PS);
877 if (pContext->state.cPixelShaderConst <= reg)
878 {
879 pContext->state.paPixelShaderConst = (PVMSVGASHADERCONST)RTMemRealloc(pContext->state.paPixelShaderConst, sizeof(VMSVGASHADERCONST) * (reg + 1));
880 AssertReturn(pContext->state.paPixelShaderConst, VERR_NO_MEMORY);
881 for (uint32_t i = pContext->state.cPixelShaderConst; i < reg + 1; i++)
882 pContext->state.paPixelShaderConst[i].fValid = false;
883 pContext->state.cPixelShaderConst = reg + 1;
884 }
885
886 pContext->state.paPixelShaderConst[reg].fValid = true;
887 pContext->state.paPixelShaderConst[reg].ctype = ctype;
888 pContext->state.paPixelShaderConst[reg].value[0] = val1;
889 pContext->state.paPixelShaderConst[reg].value[1] = val2;
890 pContext->state.paPixelShaderConst[reg].value[2] = val3;
891 pContext->state.paPixelShaderConst[reg].value[3] = val4;
892 }
893
894 return VINF_SUCCESS;
895}
896
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