VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-shared.h@ 57041

Last change on this file since 57041 was 56947, checked in by vboxsync, 9 years ago

vmsvga3dShaderSet: Restore fix, i.e. when pContext is not NULL.

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