VirtualBox

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

最後變更 在這個檔案從69415是 69415,由 vboxsync 提交於 7 年 前

Devices/Graphics: VMSVGA occlusion queries

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 43.1 KB
 
1/* $Id: DevVGA-SVGA3d-savedstate.cpp 69415 2017-10-27 10:00:34Z 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.alldomusa.eu.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 < RT_ELEMENTS(pContext->state.aTextureStates); ++iStage)
87 {
88 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTextureStates[0]); ++j)
89 {
90 SVGA3dTextureState *pTextureState = &pContext->state.aTextureStates[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(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 if (uVersion >= VGA_SAVEDSTATE_VERSION_VMSVGA_TEX_STAGES)
313 {
314 /* Load texture stage and samplers state. */
315
316 /* Number of stages/samplers. */
317 uint32_t cStages;
318 rc = SSMR3GetU32(pSSM, &cStages);
319 AssertRCReturn(rc, rc);
320
321 /* Number of states. */
322 uint32_t cTextureStates;
323 rc = SSMR3GetU32(pSSM, &cTextureStates);
324 AssertRCReturn(rc, rc);
325
326 for (uint32_t iStage = 0; iStage < cStages; ++iStage)
327 {
328 for (uint32_t j = 0; j < cTextureStates; ++j)
329 {
330 SVGA3dTextureState textureState;
331 SSMR3GetU32(pSSM, &textureState.stage);
332 uint32_t u32Name;
333 SSMR3GetU32(pSSM, &u32Name);
334 textureState.name = (SVGA3dTextureStateName)u32Name;
335 rc = SSMR3GetU32(pSSM, &textureState.value);
336 AssertRCReturn(rc, rc);
337
338 if ( iStage < RT_ELEMENTS(pContext->state.aTextureStates)
339 && j < RT_ELEMENTS(pContext->state.aTextureStates[0]))
340 {
341 pContext->state.aTextureStates[iStage][j] = textureState;
342 }
343 }
344 }
345 }
346
347#if 0 /** @todo */
348 if (uVersion >= VGA_SAVEDSTATE_VERSION_VMSVGA_TEX_STAGES) /** @todo VGA_SAVEDSTATE_VERSION_VMSVGA_3D */
349 {
350 VMSVGA3DQUERY query;
351 RT_ZERO(query);
352
353 rc = SSMR3GetStructEx(pSSM, &query, sizeof(query), 0, g_aVMSVGA3DQUERYFields, NULL);
354 AssertRCReturn(rc, rc);
355
356 switch (query.enmQueryState)
357 {
358 case VMSVGA3DQUERYSTATE_BUILDING:
359 /* Start collecting data. */
360 vmsvga3dQueryBegin(pThis, cid, SVGA3D_QUERYTYPE_OCCLUSION);
361 /* Partial result. */
362 pContext->occlusion.u32QueryResult = query.u32QueryResult;
363 break;
364
365 case VMSVGA3DQUERYSTATE_ISSUED:
366 /* Guest ended the query but did not read result. Result is restored. */
367 query.enmQueryState = VMSVGA3DQUERYSTATE_SIGNALED;
368 RT_FALL_THRU();
369 case VMSVGA3DQUERYSTATE_SIGNALED:
370 /* Create the query object. */
371 vmsvga3dOcclusionQueryCreate(pState, pContext);
372
373 /* Update result and state. */
374 pContext->occlusion.enmQueryState = query.enmQueryState;
375 pContext->occlusion.u32QueryResult = query.u32QueryResult;
376 break;
377
378 default:
379 AssertFailed();
380 RT_FALL_THRU();
381 case VMSVGA3DQUERYSTATE_NULL:
382 RT_ZERO(pContext->occlusion);
383 break;
384 }
385 }
386#endif
387 }
388 }
389
390#ifdef VMSVGA3D_OPENGL
391 /* Make the shared context the current one. */
392 if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
393 VMSVGA3D_SET_CURRENT_CONTEXT(pState, &pState->SharedCtx);
394#endif
395
396 /* Fetch all surfaces. */
397 for (uint32_t i = 0; i < cSurfaces; i++)
398 {
399 uint32_t sid;
400
401 /* Fetch the id first. */
402 rc = SSMR3GetU32(pSSM, &sid);
403 AssertRCReturn(rc, rc);
404
405 if (sid != SVGA3D_INVALID_ID)
406 {
407 VMSVGA3DSURFACE surface;
408 LogFlow(("vmsvga3dLoadExec: Loading sid=%#x\n", sid));
409
410 /* Fetch the surface structure first. */
411 rc = SSMR3GetStructEx(pSSM, &surface, sizeof(surface), 0, g_aVMSVGA3DSURFACEFields, NULL);
412 AssertRCReturn(rc, rc);
413
414 {
415 uint32_t cMipLevels = surface.faces[0].numMipLevels * surface.cFaces;
416 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = (PVMSVGA3DMIPMAPLEVEL)RTMemAlloc(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL));
417 AssertReturn(pMipmapLevel, VERR_NO_MEMORY);
418 SVGA3dSize *pMipmapLevelSize = (SVGA3dSize *)RTMemAlloc(cMipLevels * sizeof(SVGA3dSize));
419 AssertReturn(pMipmapLevelSize, VERR_NO_MEMORY);
420
421 /* Load the mip map level info. */
422 for (uint32_t face=0; face < surface.cFaces; face++)
423 {
424 for (uint32_t j = 0; j < surface.faces[0].numMipLevels; j++)
425 {
426 uint32_t idx = j + face * surface.faces[0].numMipLevels;
427 /* Load the mip map level struct. */
428 rc = SSMR3GetStructEx(pSSM, &pMipmapLevel[idx], sizeof(pMipmapLevel[idx]), 0, g_aVMSVGA3DMIPMAPLEVELFields, NULL);
429 AssertRCReturn(rc, rc);
430
431 pMipmapLevelSize[idx] = pMipmapLevel[idx].mipmapSize;
432 }
433 }
434
435 rc = vmsvga3dSurfaceDefine(pThis, sid, surface.surfaceFlags, surface.format, surface.faces, surface.multiSampleCount, surface.autogenFilter, cMipLevels, pMipmapLevelSize);
436 AssertRCReturn(rc, rc);
437
438 RTMemFree(pMipmapLevelSize);
439 RTMemFree(pMipmapLevel);
440 }
441
442 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
443 Assert(pSurface->id == sid);
444
445 pSurface->fDirty = false;
446
447 /* Load the mip map level data. */
448 for (uint32_t j = 0; j < pSurface->faces[0].numMipLevels * pSurface->cFaces; j++)
449 {
450 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[j];
451 bool fDataPresent = false;
452
453 /* vmsvga3dSurfaceDefine already allocated the surface data buffer. */
454 Assert(pMipmapLevel->cbSurface);
455 AssertReturn(pMipmapLevel->pSurfaceData, VERR_INTERNAL_ERROR);
456
457 /* Fetch the data present boolean first. */
458 rc = SSMR3GetBool(pSSM, &fDataPresent);
459 AssertRCReturn(rc, rc);
460
461 Log(("Surface sid=%x: load mipmap level %d with %x bytes data (present=%d).\n", sid, j, pMipmapLevel->cbSurface, fDataPresent));
462
463 if (fDataPresent)
464 {
465 rc = SSMR3GetMem(pSSM, pMipmapLevel->pSurfaceData, pMipmapLevel->cbSurface);
466 AssertRCReturn(rc, rc);
467 pMipmapLevel->fDirty = true;
468 pSurface->fDirty = true;
469 }
470 else
471 {
472 pMipmapLevel->fDirty = false;
473 }
474 }
475 }
476 }
477
478#ifdef VMSVGA3D_OPENGL
479 /* Reinitialize the shared context. */
480 LogFlow(("vmsvga3dLoadExec: pState->SharedCtx.id=%#x\n", pState->SharedCtx.id));
481 if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
482 {
483 rc = vmsvga3dLoadReinitContext(pThis, &pState->SharedCtx);
484 AssertRCReturn(rc, rc);
485 }
486#endif
487
488 /* Reinitialize all active contexts. */
489 for (uint32_t i = 0; i < pState->cContexts; i++)
490 {
491 PVMSVGA3DCONTEXT pContext = pState->papContexts[i];
492 if (pContext->id != SVGA3D_INVALID_ID)
493 {
494 rc = vmsvga3dLoadReinitContext(pThis, pContext);
495 AssertRCReturn(rc, rc);
496 }
497 }
498
499 LogFlow(("vmsvga3dLoadExec: return success\n"));
500 return VINF_SUCCESS;
501}
502
503
504static int vmsvga3dSaveContext(PVGASTATE pThis, PSSMHANDLE pSSM, PVMSVGA3DCONTEXT pContext)
505{
506 RT_NOREF(pThis);
507 uint32_t cid = pContext->id;
508
509 /* Save the id first. */
510 int rc = SSMR3PutU32(pSSM, cid);
511 AssertRCReturn(rc, rc);
512
513 if (cid != SVGA3D_INVALID_ID)
514 {
515 /* Save a copy of the context structure first. */
516 rc = SSMR3PutStructEx(pSSM, pContext, sizeof(*pContext), 0, g_aVMSVGA3DCONTEXTFields, NULL);
517 AssertRCReturn(rc, rc);
518
519 /* Save all pixel shaders. */
520 for (uint32_t j = 0; j < pContext->cPixelShaders; j++)
521 {
522 PVMSVGA3DSHADER pShader = &pContext->paPixelShader[j];
523
524 /* Save the id first. */
525 rc = SSMR3PutU32(pSSM, pShader->id);
526 AssertRCReturn(rc, rc);
527
528 if (pShader->id != SVGA3D_INVALID_ID)
529 {
530 uint32_t cbData = pShader->cbData;
531
532 /* Save a copy of the shader struct. */
533 rc = SSMR3PutStructEx(pSSM, pShader, sizeof(*pShader), 0, g_aVMSVGA3DSHADERFields, NULL);
534 AssertRCReturn(rc, rc);
535
536 Log(("Save pixelshader shid=%d with %x bytes code.\n", pShader->id, cbData));
537 rc = SSMR3PutMem(pSSM, pShader->pShaderProgram, cbData);
538 AssertRCReturn(rc, rc);
539 }
540 }
541
542 /* Save all vertex shaders. */
543 for (uint32_t j = 0; j < pContext->cVertexShaders; j++)
544 {
545 PVMSVGA3DSHADER pShader = &pContext->paVertexShader[j];
546
547 /* Save the id first. */
548 rc = SSMR3PutU32(pSSM, pShader->id);
549 AssertRCReturn(rc, rc);
550
551 if (pShader->id != SVGA3D_INVALID_ID)
552 {
553 uint32_t cbData = pShader->cbData;
554
555 /* Save a copy of the shader struct. */
556 rc = SSMR3PutStructEx(pSSM, pShader, sizeof(*pShader), 0, g_aVMSVGA3DSHADERFields, NULL);
557 AssertRCReturn(rc, rc);
558
559 Log(("Save vertex shader shid=%d with %x bytes code.\n", pShader->id, cbData));
560 /* Fetch the shader code and save it. */
561 rc = SSMR3PutMem(pSSM, pShader->pShaderProgram, cbData);
562 AssertRCReturn(rc, rc);
563 }
564 }
565
566 /* Save pixel shader constants. */
567 for (uint32_t j = 0; j < pContext->state.cPixelShaderConst; j++)
568 {
569 rc = SSMR3PutStructEx(pSSM, &pContext->state.paPixelShaderConst[j], sizeof(pContext->state.paPixelShaderConst[j]), 0, g_aVMSVGASHADERCONSTFields, NULL);
570 AssertRCReturn(rc, rc);
571 }
572
573 /* Save vertex shader constants. */
574 for (uint32_t j = 0; j < pContext->state.cVertexShaderConst; j++)
575 {
576 rc = SSMR3PutStructEx(pSSM, &pContext->state.paVertexShaderConst[j], sizeof(pContext->state.paVertexShaderConst[j]), 0, g_aVMSVGASHADERCONSTFields, NULL);
577 AssertRCReturn(rc, rc);
578 }
579
580 /* Save texture stage and samplers state. */
581
582 /* Number of stages/samplers. */
583 rc = SSMR3PutU32(pSSM, RT_ELEMENTS(pContext->state.aTextureStates));
584 AssertRCReturn(rc, rc);
585
586 /* Number of texture states. */
587 rc = SSMR3PutU32(pSSM, RT_ELEMENTS(pContext->state.aTextureStates[0]));
588 AssertRCReturn(rc, rc);
589
590 for (uint32_t iStage = 0; iStage < RT_ELEMENTS(pContext->state.aTextureStates); ++iStage)
591 {
592 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTextureStates[0]); ++j)
593 {
594 SVGA3dTextureState *pTextureState = &pContext->state.aTextureStates[iStage][j];
595
596 SSMR3PutU32(pSSM, pTextureState->stage);
597 SSMR3PutU32(pSSM, pTextureState->name);
598 rc = SSMR3PutU32(pSSM, pTextureState->value);
599 AssertRCReturn(rc, rc);
600 }
601 }
602
603#if 0 /** @todo Enable later. */
604 PVMSVGA3DSTATE pState = pThis->svga.p3dState;
605 /* Occlusion query. */
606 if (!VMSVGA3DQUERY_EXISTS(&pContext->occlusion))
607 {
608 pContext->occlusion.enmQueryState = VMSVGA3DQUERYSTATE_NULL;
609 }
610
611 switch (pContext->occlusion.enmQueryState)
612 {
613 case VMSVGA3DQUERYSTATE_BUILDING:
614 /* Stop collecting data. Fetch partial result. Save result. */
615 vmsvga3dOcclusionQueryEnd(pState, pContext);
616 RT_FALL_THRU();
617 case VMSVGA3DQUERYSTATE_ISSUED:
618 /* Fetch result. Save result. */
619 pContext->occlusion.u32QueryResult = 0;
620 vmsvga3dOcclusionQueryGetData(pState, pContext, &pContext->occlusion.u32QueryResult);
621 RT_FALL_THRU();
622 case VMSVGA3DQUERYSTATE_SIGNALED:
623 /* Save result. Nothing to do here. */
624 break;
625
626 default:
627 AssertFailed();
628 RT_FALL_THRU();
629 case VMSVGA3DQUERYSTATE_NULL:
630 pContext->occlusion.enmQueryState = VMSVGA3DQUERYSTATE_NULL;
631 pContext->occlusion.u32QueryResult = 0;
632 break;
633 }
634
635 rc = SSMR3PutStructEx(pSSM, &pContext->occlusion, sizeof(pContext->occlusion), 0, g_aVMSVGA3DQUERYFields, NULL);
636 AssertRCReturn(rc, rc);
637#endif
638 }
639
640 return VINF_SUCCESS;
641}
642
643int vmsvga3dSaveExec(PVGASTATE pThis, PSSMHANDLE pSSM)
644{
645 PVMSVGA3DSTATE pState = pThis->svga.p3dState;
646 AssertReturn(pState, VERR_NO_MEMORY);
647 int rc;
648
649 /* Save a copy of the generic 3d state first. */
650 rc = SSMR3PutStructEx(pSSM, pState, sizeof(*pState), 0, g_aVMSVGA3DSTATEFields, NULL);
651 AssertRCReturn(rc, rc);
652
653#ifdef VMSVGA3D_OPENGL
654 /* Save the shared context. */
655 if (pState->SharedCtx.id == VMSVGA3D_SHARED_CTX_ID)
656 {
657 rc = vmsvga3dSaveContext(pThis, pSSM, &pState->SharedCtx);
658 AssertRCReturn(rc, rc);
659 }
660#endif
661
662 /* Save all active contexts. */
663 for (uint32_t i = 0; i < pState->cContexts; i++)
664 {
665 rc = vmsvga3dSaveContext(pThis, pSSM, pState->papContexts[i]);
666 AssertRCReturn(rc, rc);
667 }
668
669 /* Save all active surfaces. */
670 for (uint32_t sid = 0; sid < pState->cSurfaces; sid++)
671 {
672 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
673
674 /* Save the id first. */
675 rc = SSMR3PutU32(pSSM, pSurface->id);
676 AssertRCReturn(rc, rc);
677
678 if (pSurface->id != SVGA3D_INVALID_ID)
679 {
680 /* Save a copy of the surface structure first. */
681 rc = SSMR3PutStructEx(pSSM, pSurface, sizeof(*pSurface), 0, g_aVMSVGA3DSURFACEFields, NULL);
682 AssertRCReturn(rc, rc);
683
684 /* Save the mip map level info. */
685 for (uint32_t face=0; face < pSurface->cFaces; face++)
686 {
687 for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
688 {
689 uint32_t idx = i + face * pSurface->faces[0].numMipLevels;
690 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[idx];
691
692 /* Save a copy of the mip map level struct. */
693 rc = SSMR3PutStructEx(pSSM, pMipmapLevel, sizeof(*pMipmapLevel), 0, g_aVMSVGA3DMIPMAPLEVELFields, NULL);
694 AssertRCReturn(rc, rc);
695 }
696 }
697
698 /* Save the mip map level data. */
699 for (uint32_t face=0; face < pSurface->cFaces; face++)
700 {
701 for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
702 {
703 uint32_t idx = i + face * pSurface->faces[0].numMipLevels;
704 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[idx];
705
706 Log(("Surface sid=%d: save mipmap level %d with %x bytes data.\n", sid, i, pMipmapLevel->cbSurface));
707
708#ifdef VMSVGA3D_DIRECT3D
709 if (!pSurface->u.pSurface)
710#else
711 if (pSurface->oglId.texture == OPENGL_INVALID_ID)
712#endif
713 {
714 if (pMipmapLevel->fDirty)
715 {
716 /* Data follows */
717 rc = SSMR3PutBool(pSSM, true);
718 AssertRCReturn(rc, rc);
719
720 Assert(pMipmapLevel->cbSurface);
721 rc = SSMR3PutMem(pSSM, pMipmapLevel->pSurfaceData, pMipmapLevel->cbSurface);
722 AssertRCReturn(rc, rc);
723 }
724 else
725 {
726 /* No data follows */
727 rc = SSMR3PutBool(pSSM, false);
728 AssertRCReturn(rc, rc);
729 }
730 }
731 else
732 {
733#ifdef VMSVGA3D_DIRECT3D
734 void *pData;
735 bool fRenderTargetTexture = false;
736 bool fTexture = false;
737 bool fSkipSave = false;
738 HRESULT hr;
739
740 Assert(pMipmapLevel->cbSurface);
741 pData = RTMemAllocZ(pMipmapLevel->cbSurface);
742 AssertReturn(pData, VERR_NO_MEMORY);
743
744 switch (pSurface->enmD3DResType)
745 {
746 case VMSVGA3D_D3DRESTYPE_CUBE_TEXTURE:
747 case VMSVGA3D_D3DRESTYPE_VOLUME_TEXTURE:
748 AssertFailed(); /// @todo
749 fSkipSave = true;
750 break;
751 case VMSVGA3D_D3DRESTYPE_SURFACE:
752 case VMSVGA3D_D3DRESTYPE_TEXTURE:
753 {
754 if (pSurface->surfaceFlags & SVGA3D_SURFACE_HINT_DEPTHSTENCIL)
755 {
756 /** @todo unable to easily fetch depth surface data in d3d 9 */
757 fSkipSave = true;
758 break;
759 }
760
761 fTexture = (pSurface->enmD3DResType == VMSVGA3D_D3DRESTYPE_TEXTURE);
762 fRenderTargetTexture = fTexture && (pSurface->surfaceFlags & SVGA3D_SURFACE_HINT_RENDERTARGET);
763
764 D3DLOCKED_RECT LockedRect;
765
766 if (fTexture)
767 {
768 if (pSurface->bounce.pTexture)
769 {
770 if ( !pSurface->fDirty
771 && fRenderTargetTexture
772 && i == 0 /* only the first time */)
773 {
774 IDirect3DSurface9 *pSrc, *pDest;
775
776 /** @todo stricter checks for associated context */
777 uint32_t cid = pSurface->idAssociatedContext;
778 if ( cid >= pState->cContexts
779 || pState->papContexts[cid]->id != cid)
780 {
781 Log(("vmsvga3dSaveExec invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
782 AssertFailedReturn(VERR_INVALID_PARAMETER);
783 }
784 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
785
786 hr = pSurface->bounce.pTexture->GetSurfaceLevel(i, &pDest);
787 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetSurfaceLevel failed with %x\n", hr), VERR_INTERNAL_ERROR);
788
789 hr = pSurface->u.pTexture->GetSurfaceLevel(i, &pSrc);
790 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetSurfaceLevel failed with %x\n", hr), VERR_INTERNAL_ERROR);
791
792 hr = pContext->pDevice->GetRenderTargetData(pSrc, pDest);
793 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetRenderTargetData failed with %x\n", hr), VERR_INTERNAL_ERROR);
794
795 pSrc->Release();
796 pDest->Release();
797 }
798
799 hr = pSurface->bounce.pTexture->LockRect(i, /* texture level */
800 &LockedRect,
801 NULL,
802 D3DLOCK_READONLY);
803 }
804 else
805 hr = pSurface->u.pTexture->LockRect(i, /* texture level */
806 &LockedRect,
807 NULL,
808 D3DLOCK_READONLY);
809 }
810 else
811 hr = pSurface->u.pSurface->LockRect(&LockedRect,
812 NULL,
813 D3DLOCK_READONLY);
814 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
815
816 /* Copy the data one line at a time in case the internal pitch is different. */
817 for (uint32_t j = 0; j < pMipmapLevel->cBlocksY; ++j)
818 {
819 uint8_t *pu8Dst = (uint8_t *)pData + j * pMipmapLevel->cbSurfacePitch;
820 const uint8_t *pu8Src = (uint8_t *)LockedRect.pBits + j * LockedRect.Pitch;
821 memcpy(pu8Dst, pu8Src, pMipmapLevel->cbSurfacePitch);
822 }
823
824 if (fTexture)
825 {
826 if (pSurface->bounce.pTexture)
827 {
828 hr = pSurface->bounce.pTexture->UnlockRect(i);
829 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: UnlockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
830 }
831 else
832 hr = pSurface->u.pTexture->UnlockRect(i);
833 }
834 else
835 hr = pSurface->u.pSurface->UnlockRect();
836 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: UnlockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
837 break;
838 }
839
840 case VMSVGA3D_D3DRESTYPE_VERTEX_BUFFER:
841 case VMSVGA3D_D3DRESTYPE_INDEX_BUFFER:
842 {
843 /* Current type of the buffer. */
844 const bool fVertex = (pSurface->enmD3DResType == VMSVGA3D_D3DRESTYPE_VERTEX_BUFFER);
845
846 uint8_t *pD3DData;
847
848 if (fVertex)
849 hr = pSurface->u.pVertexBuffer->Lock(0, 0, (void **)&pD3DData, D3DLOCK_READONLY);
850 else
851 hr = pSurface->u.pIndexBuffer->Lock(0, 0, (void **)&pD3DData, D3DLOCK_READONLY);
852 AssertMsg(hr == D3D_OK, ("vmsvga3dSaveExec: Lock %s failed with %x\n", (fVertex) ? "vertex" : "index", hr));
853
854 memcpy(pData, pD3DData, pMipmapLevel->cbSurface);
855
856 if (fVertex)
857 hr = pSurface->u.pVertexBuffer->Unlock();
858 else
859 hr = pSurface->u.pIndexBuffer->Unlock();
860 AssertMsg(hr == D3D_OK, ("vmsvga3dSaveExec: Unlock %s failed with %x\n", (fVertex) ? "vertex" : "index", hr));
861 break;
862 }
863
864 default:
865 AssertFailed();
866 break;
867 }
868
869 if (!fSkipSave)
870 {
871 /* Data follows */
872 rc = SSMR3PutBool(pSSM, true);
873 AssertRCReturn(rc, rc);
874
875 /* And write the surface data. */
876 rc = SSMR3PutMem(pSSM, pData, pMipmapLevel->cbSurface);
877 AssertRCReturn(rc, rc);
878 }
879 else
880 {
881 /* No data follows */
882 rc = SSMR3PutBool(pSSM, false);
883 AssertRCReturn(rc, rc);
884 }
885
886 RTMemFree(pData);
887#elif defined(VMSVGA3D_OPENGL)
888 void *pData = NULL;
889
890 PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
891 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
892
893 Assert(pMipmapLevel->cbSurface);
894
895 switch (pSurface->surfaceFlags & VMSVGA3D_SURFACE_HINT_SWITCH_MASK)
896 {
897 default:
898 AssertFailed();
899 RT_FALL_THRU();
900 case SVGA3D_SURFACE_HINT_DEPTHSTENCIL:
901 case SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE:
902 /** @todo fetch data from the renderbuffer */
903 /* No data follows */
904 rc = SSMR3PutBool(pSSM, false);
905 AssertRCReturn(rc, rc);
906 break;
907
908 case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
909 case SVGA3D_SURFACE_HINT_TEXTURE:
910 case SVGA3D_SURFACE_HINT_RENDERTARGET:
911 {
912 GLint activeTexture;
913
914 pData = RTMemAllocZ(pMipmapLevel->cbSurface);
915 AssertReturn(pData, VERR_NO_MEMORY);
916
917 glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
918 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
919
920 glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
921 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
922
923 /* Set row length and alignment of the output data. */
924 VMSVGAPACKPARAMS SavedParams;
925 vmsvga3dOglSetPackParams(pState, pContext, pSurface, &SavedParams);
926
927 glGetTexImage(GL_TEXTURE_2D,
928 i,
929 pSurface->formatGL,
930 pSurface->typeGL,
931 pData);
932 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
933
934 vmsvga3dOglRestorePackParams(pState, pContext, pSurface, &SavedParams);
935
936 /* Data follows */
937 rc = SSMR3PutBool(pSSM, true);
938 AssertRCReturn(rc, rc);
939
940 /* And write the surface data. */
941 rc = SSMR3PutMem(pSSM, pData, pMipmapLevel->cbSurface);
942 AssertRCReturn(rc, rc);
943
944 /* Restore the old active texture. */
945 glBindTexture(GL_TEXTURE_2D, activeTexture);
946 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
947 break;
948 }
949
950 case SVGA3D_SURFACE_HINT_VERTEXBUFFER | SVGA3D_SURFACE_HINT_INDEXBUFFER:
951 case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
952 case SVGA3D_SURFACE_HINT_INDEXBUFFER:
953 {
954 uint8_t *pBufferData;
955
956 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer);
957 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
958
959 pBufferData = (uint8_t *)pState->ext.glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
960 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
961 Assert(pBufferData);
962
963 /* Data follows */
964 rc = SSMR3PutBool(pSSM, true);
965 AssertRCReturn(rc, rc);
966
967 /* And write the surface data. */
968 rc = SSMR3PutMem(pSSM, pBufferData, pMipmapLevel->cbSurface);
969 AssertRCReturn(rc, rc);
970
971 pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);
972 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
973
974 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0);
975 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
976
977 }
978 }
979 if (pData)
980 RTMemFree(pData);
981#else
982#error "Unexpected 3d backend"
983#endif
984 }
985 }
986 }
987 }
988 }
989 return VINF_SUCCESS;
990}
991
992int vmsvga3dSaveShaderConst(PVMSVGA3DCONTEXT pContext, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype,
993 uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4)
994{
995 /* Choose a sane upper limit. */
996 AssertReturn(reg < _32K, VERR_INVALID_PARAMETER);
997
998 if (type == SVGA3D_SHADERTYPE_VS)
999 {
1000 if (pContext->state.cVertexShaderConst <= reg)
1001 {
1002 pContext->state.paVertexShaderConst = (PVMSVGASHADERCONST)RTMemRealloc(pContext->state.paVertexShaderConst, sizeof(VMSVGASHADERCONST) * (reg + 1));
1003 AssertReturn(pContext->state.paVertexShaderConst, VERR_NO_MEMORY);
1004 for (uint32_t i = pContext->state.cVertexShaderConst; i < reg + 1; i++)
1005 pContext->state.paVertexShaderConst[i].fValid = false;
1006 pContext->state.cVertexShaderConst = reg + 1;
1007 }
1008
1009 pContext->state.paVertexShaderConst[reg].fValid = true;
1010 pContext->state.paVertexShaderConst[reg].ctype = ctype;
1011 pContext->state.paVertexShaderConst[reg].value[0] = val1;
1012 pContext->state.paVertexShaderConst[reg].value[1] = val2;
1013 pContext->state.paVertexShaderConst[reg].value[2] = val3;
1014 pContext->state.paVertexShaderConst[reg].value[3] = val4;
1015 }
1016 else
1017 {
1018 Assert(type == SVGA3D_SHADERTYPE_PS);
1019 if (pContext->state.cPixelShaderConst <= reg)
1020 {
1021 pContext->state.paPixelShaderConst = (PVMSVGASHADERCONST)RTMemRealloc(pContext->state.paPixelShaderConst, sizeof(VMSVGASHADERCONST) * (reg + 1));
1022 AssertReturn(pContext->state.paPixelShaderConst, VERR_NO_MEMORY);
1023 for (uint32_t i = pContext->state.cPixelShaderConst; i < reg + 1; i++)
1024 pContext->state.paPixelShaderConst[i].fValid = false;
1025 pContext->state.cPixelShaderConst = reg + 1;
1026 }
1027
1028 pContext->state.paPixelShaderConst[reg].fValid = true;
1029 pContext->state.paPixelShaderConst[reg].ctype = ctype;
1030 pContext->state.paPixelShaderConst[reg].value[0] = val1;
1031 pContext->state.paPixelShaderConst[reg].value[1] = val2;
1032 pContext->state.paPixelShaderConst[reg].value[2] = val3;
1033 pContext->state.paPixelShaderConst[reg].value[3] = val4;
1034 }
1035
1036 return VINF_SUCCESS;
1037}
1038
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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