VirtualBox

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

Last change on this file since 69153 was 69153, checked in by vboxsync, 7 years ago

Devices/Graphics: VMSVGA: Initial support for volume textures. Remember the type of created D3D resource.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 37.7 KB
Line 
1/* $Id: DevVGA-SVGA3d-savedstate.cpp 69153 2017-10-22 09:38:04Z vboxsync $ */
2/** @file
3 * DevSVGA3d - VMWare SVGA device, 3D parts - Saved state and assocated stuff.
4 */
5
6/*
7 * Copyright (C) 2013-2017 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].mipmapSize;
356 }
357 }
358
359 rc = vmsvga3dSurfaceDefine(pThis, sid, surface.surfaceFlags, 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 /* vmsvga3dSurfaceDefine already allocated the surface data buffer. */
378 Assert(pMipmapLevel->cbSurface);
379 AssertReturn(pMipmapLevel->pSurfaceData, VERR_INTERNAL_ERROR);
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 fSkipSave = false;
603 HRESULT hr;
604
605 Assert(pMipmapLevel->cbSurface);
606 pData = RTMemAllocZ(pMipmapLevel->cbSurface);
607 AssertReturn(pData, VERR_NO_MEMORY);
608
609 switch (pSurface->enmD3DResType)
610 {
611 case VMSVGA3D_D3DRESTYPE_CUBE_TEXTURE:
612 case VMSVGA3D_D3DRESTYPE_VOLUME_TEXTURE:
613 AssertFailed(); ///@todo
614 fSkipSave = true;
615 break;
616 case VMSVGA3D_D3DRESTYPE_SURFACE:
617 case VMSVGA3D_D3DRESTYPE_TEXTURE:
618 {
619 if (pSurface->surfaceFlags & SVGA3D_SURFACE_HINT_DEPTHSTENCIL)
620 {
621 /** @todo unable to easily fetch depth surface data in d3d 9 */
622 fSkipSave = true;
623 break;
624 }
625
626 fTexture = (pSurface->enmD3DResType == VMSVGA3D_D3DRESTYPE_TEXTURE);
627 fRenderTargetTexture = fTexture && (pSurface->surfaceFlags & SVGA3D_SURFACE_HINT_RENDERTARGET);
628
629 D3DLOCKED_RECT LockedRect;
630
631 if (fTexture)
632 {
633 if (pSurface->bounce.pTexture)
634 {
635 if ( !pSurface->fDirty
636 && fRenderTargetTexture
637 && i == 0 /* only the first time */)
638 {
639 IDirect3DSurface9 *pSrc, *pDest;
640
641 /** @todo stricter checks for associated context */
642 uint32_t cid = pSurface->idAssociatedContext;
643 if ( cid >= pState->cContexts
644 || pState->papContexts[cid]->id != cid)
645 {
646 Log(("vmsvga3dSaveExec invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
647 AssertFailedReturn(VERR_INVALID_PARAMETER);
648 }
649 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
650
651 hr = pSurface->bounce.pTexture->GetSurfaceLevel(i, &pDest);
652 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetSurfaceLevel failed with %x\n", hr), VERR_INTERNAL_ERROR);
653
654 hr = pSurface->u.pTexture->GetSurfaceLevel(i, &pSrc);
655 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetSurfaceLevel failed with %x\n", hr), VERR_INTERNAL_ERROR);
656
657 hr = pContext->pDevice->GetRenderTargetData(pSrc, pDest);
658 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetRenderTargetData failed with %x\n", hr), VERR_INTERNAL_ERROR);
659
660 pSrc->Release();
661 pDest->Release();
662 }
663
664 hr = pSurface->bounce.pTexture->LockRect(i, /* texture level */
665 &LockedRect,
666 NULL,
667 D3DLOCK_READONLY);
668 }
669 else
670 hr = pSurface->u.pTexture->LockRect(i, /* texture level */
671 &LockedRect,
672 NULL,
673 D3DLOCK_READONLY);
674 }
675 else
676 hr = pSurface->u.pSurface->LockRect(&LockedRect,
677 NULL,
678 D3DLOCK_READONLY);
679 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
680
681 /* Copy the data one line at a time in case the internal pitch is different. */
682 for (uint32_t j = 0; j < pMipmapLevel->cBlocksY; ++j)
683 {
684 uint8_t *pu8Dst = (uint8_t *)pData + j * pMipmapLevel->cbSurfacePitch;
685 const uint8_t *pu8Src = (uint8_t *)LockedRect.pBits + j * LockedRect.Pitch;
686 memcpy(pu8Dst, pu8Src, pMipmapLevel->cbSurfacePitch);
687 }
688
689 if (fTexture)
690 {
691 if (pSurface->bounce.pTexture)
692 {
693 hr = pSurface->bounce.pTexture->UnlockRect(i);
694 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: UnlockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
695 }
696 else
697 hr = pSurface->u.pTexture->UnlockRect(i);
698 }
699 else
700 hr = pSurface->u.pSurface->UnlockRect();
701 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: UnlockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
702 break;
703 }
704
705 case VMSVGA3D_D3DRESTYPE_VERTEX_BUFFER:
706 case VMSVGA3D_D3DRESTYPE_INDEX_BUFFER:
707 {
708 /* Current type of the buffer. */
709 const bool fVertex = (pSurface->enmD3DResType == VMSVGA3D_D3DRESTYPE_VERTEX_BUFFER);
710
711 uint8_t *pD3DData;
712
713 if (fVertex)
714 hr = pSurface->u.pVertexBuffer->Lock(0, 0, (void **)&pD3DData, D3DLOCK_READONLY);
715 else
716 hr = pSurface->u.pIndexBuffer->Lock(0, 0, (void **)&pD3DData, D3DLOCK_READONLY);
717 AssertMsg(hr == D3D_OK, ("vmsvga3dSaveExec: Lock %s failed with %x\n", (fVertex) ? "vertex" : "index", hr));
718
719 memcpy(pData, pD3DData, pMipmapLevel->cbSurface);
720
721 if (fVertex)
722 hr = pSurface->u.pVertexBuffer->Unlock();
723 else
724 hr = pSurface->u.pIndexBuffer->Unlock();
725 AssertMsg(hr == D3D_OK, ("vmsvga3dSaveExec: Unlock %s failed with %x\n", (fVertex) ? "vertex" : "index", hr));
726 break;
727 }
728
729 default:
730 AssertFailed();
731 break;
732 }
733
734 if (!fSkipSave)
735 {
736 /* Data follows */
737 rc = SSMR3PutBool(pSSM, true);
738 AssertRCReturn(rc, rc);
739
740 /* And write the surface data. */
741 rc = SSMR3PutMem(pSSM, pData, pMipmapLevel->cbSurface);
742 AssertRCReturn(rc, rc);
743 }
744 else
745 {
746 /* No data follows */
747 rc = SSMR3PutBool(pSSM, false);
748 AssertRCReturn(rc, rc);
749 }
750
751 RTMemFree(pData);
752#elif defined(VMSVGA3D_OPENGL)
753 void *pData = NULL;
754
755 PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
756 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
757
758 Assert(pMipmapLevel->cbSurface);
759
760 switch (pSurface->surfaceFlags & VMSVGA3D_SURFACE_HINT_SWITCH_MASK)
761 {
762 default:
763 AssertFailed();
764 RT_FALL_THRU();
765 case SVGA3D_SURFACE_HINT_DEPTHSTENCIL:
766 case SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE:
767 /** @todo fetch data from the renderbuffer */
768 /* No data follows */
769 rc = SSMR3PutBool(pSSM, false);
770 AssertRCReturn(rc, rc);
771 break;
772
773 case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
774 case SVGA3D_SURFACE_HINT_TEXTURE:
775 case SVGA3D_SURFACE_HINT_RENDERTARGET:
776 {
777 GLint activeTexture;
778
779 pData = RTMemAllocZ(pMipmapLevel->cbSurface);
780 AssertReturn(pData, VERR_NO_MEMORY);
781
782 glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
783 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
784
785 glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
786 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
787
788 /* Set row length and alignment of the output data. */
789 VMSVGAPACKPARAMS SavedParams;
790 vmsvga3dOglSetPackParams(pState, pContext, pSurface, &SavedParams);
791
792 glGetTexImage(GL_TEXTURE_2D,
793 i,
794 pSurface->formatGL,
795 pSurface->typeGL,
796 pData);
797 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
798
799 vmsvga3dOglRestorePackParams(pState, pContext, pSurface, &SavedParams);
800
801 /* Data follows */
802 rc = SSMR3PutBool(pSSM, true);
803 AssertRCReturn(rc, rc);
804
805 /* And write the surface data. */
806 rc = SSMR3PutMem(pSSM, pData, pMipmapLevel->cbSurface);
807 AssertRCReturn(rc, rc);
808
809 /* Restore the old active texture. */
810 glBindTexture(GL_TEXTURE_2D, activeTexture);
811 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
812 break;
813 }
814
815 case SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_INDEXBUFFER:
816 case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
817 case SVGA3D_SURFACE_HINT_INDEXBUFFER:
818 {
819 uint8_t *pBufferData;
820
821 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer);
822 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
823
824 pBufferData = (uint8_t *)pState->ext.glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
825 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
826 Assert(pBufferData);
827
828 /* Data follows */
829 rc = SSMR3PutBool(pSSM, true);
830 AssertRCReturn(rc, rc);
831
832 /* And write the surface data. */
833 rc = SSMR3PutMem(pSSM, pBufferData, pMipmapLevel->cbSurface);
834 AssertRCReturn(rc, rc);
835
836 pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);
837 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
838
839 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0);
840 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
841
842 }
843 }
844 if (pData)
845 RTMemFree(pData);
846#else
847#error "Unexpected 3d backend"
848#endif
849 }
850 }
851 }
852 }
853 }
854 return VINF_SUCCESS;
855}
856
857int vmsvga3dSaveShaderConst(PVMSVGA3DCONTEXT pContext, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype,
858 uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4)
859{
860 /* Choose a sane upper limit. */
861 AssertReturn(reg < _32K, VERR_INVALID_PARAMETER);
862
863 if (type == SVGA3D_SHADERTYPE_VS)
864 {
865 if (pContext->state.cVertexShaderConst <= reg)
866 {
867 pContext->state.paVertexShaderConst = (PVMSVGASHADERCONST)RTMemRealloc(pContext->state.paVertexShaderConst, sizeof(VMSVGASHADERCONST) * (reg + 1));
868 AssertReturn(pContext->state.paVertexShaderConst, VERR_NO_MEMORY);
869 for (uint32_t i = pContext->state.cVertexShaderConst; i < reg + 1; i++)
870 pContext->state.paVertexShaderConst[i].fValid = false;
871 pContext->state.cVertexShaderConst = reg + 1;
872 }
873
874 pContext->state.paVertexShaderConst[reg].fValid = true;
875 pContext->state.paVertexShaderConst[reg].ctype = ctype;
876 pContext->state.paVertexShaderConst[reg].value[0] = val1;
877 pContext->state.paVertexShaderConst[reg].value[1] = val2;
878 pContext->state.paVertexShaderConst[reg].value[2] = val3;
879 pContext->state.paVertexShaderConst[reg].value[3] = val4;
880 }
881 else
882 {
883 Assert(type == SVGA3D_SHADERTYPE_PS);
884 if (pContext->state.cPixelShaderConst <= reg)
885 {
886 pContext->state.paPixelShaderConst = (PVMSVGASHADERCONST)RTMemRealloc(pContext->state.paPixelShaderConst, sizeof(VMSVGASHADERCONST) * (reg + 1));
887 AssertReturn(pContext->state.paPixelShaderConst, VERR_NO_MEMORY);
888 for (uint32_t i = pContext->state.cPixelShaderConst; i < reg + 1; i++)
889 pContext->state.paPixelShaderConst[i].fValid = false;
890 pContext->state.cPixelShaderConst = reg + 1;
891 }
892
893 pContext->state.paPixelShaderConst[reg].fValid = true;
894 pContext->state.paPixelShaderConst[reg].ctype = ctype;
895 pContext->state.paPixelShaderConst[reg].value[0] = val1;
896 pContext->state.paPixelShaderConst[reg].value[1] = val2;
897 pContext->state.paPixelShaderConst[reg].value[2] = val3;
898 pContext->state.paPixelShaderConst[reg].value[3] = val4;
899 }
900
901 return VINF_SUCCESS;
902}
903
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