VirtualBox

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

Last change on this file since 55998 was 55811, checked in by vboxsync, 10 years ago

DevVGA-SVGA3d-ogl.cpp,++: A couple of minor fixes and more GL success assertions.

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