VirtualBox

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

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

VMSVGA3d: build fixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 81.1 KB
Line 
1/* $Id: DevVGA-SVGA3d-shared.h 57082 2015-07-26 20:45:54Z vboxsync $ */
2/** @file
3 * DevVMWare - VMWare SVGA device, shared part.
4 *
5 * @remarks This is code that's very similar on both for OpenGL and D3D
6 * backends, so instead of moving backend specific structures
7 * into header files with #ifdefs and stuff, we just include
8 * the code into the backend implementation source file.
9 */
10
11/*
12 * Copyright (C) 2013-2015 Oracle Corporation
13 *
14 * This file is part of VirtualBox Open Source Edition (OSE), as
15 * available from http://www.virtualbox.org. This file is free software;
16 * you can redistribute it and/or modify it under the terms of the GNU
17 * General Public License (GPL) as published by the Free Software
18 * Foundation, in version 2 as it comes in the "COPYING" file of the
19 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
20 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
21 */
22
23#ifndef ___DevVGA_SVGA3d_shared_h___
24#define ___DevVGA_SVGA3d_shared_h___
25
26/**
27 * Worker for vmsvga3dUpdateHeapBuffersForSurfaces.
28 *
29 * This will allocate heap buffers if necessary, thus increasing the memory
30 * usage of the process.
31 *
32 * @todo Would be interesting to share this code with the saved state code.
33 *
34 * @returns VBox status code.
35 * @param pState The 3D state structure.
36 * @param pSurface The surface to refresh the heap buffers for.
37 */
38static int vmsvga3dSurfaceUpdateHeapBuffers(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface)
39{
40 /*
41 * Currently we've got trouble retreving bit for DEPTHSTENCIL
42 * surfaces both for OpenGL and D3D, so skip these here (don't
43 * wast memory on them).
44 */
45 uint32_t const fSwitchFlags = pSurface->flags
46 & ( SVGA3D_SURFACE_HINT_INDEXBUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER
47 | SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET
48 | SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_CUBEMAP);
49 if ( fSwitchFlags != SVGA3D_SURFACE_HINT_DEPTHSTENCIL
50 && fSwitchFlags != (SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE))
51 {
52
53#ifdef VMSVGA3D_OPENGL
54 /*
55 * Change OpenGL context to the one the surface is associated with.
56 */
57# ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
58 PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
59 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
60# else
61 /** @todo stricter checks for associated context */
62 uint32_t cid = pSurface->idAssociatedContext;
63 if ( cid >= pState->cContexts
64 || pState->papContexts[cid]->id != cid)
65 {
66 Log(("vmsvga3dSurfaceUpdateHeapBuffers: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
67 AssertFailedReturn(VERR_INVALID_PARAMETER);
68 }
69 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
70 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
71# endif
72#endif
73
74 /*
75 * Work thru each mipmap level for each face.
76 */
77 for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
78 {
79 Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels);
80 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[iFace * pSurface->faces[0].numMipLevels];
81 for (uint32_t i = 0; i < pSurface->faces[iFace].numMipLevels; i++, pMipmapLevel++)
82 {
83#ifdef VMSVGA3D_DIRECT3D
84 if (pSurface->u.pSurface)
85#else
86 if (pSurface->oglId.texture != OPENGL_INVALID_ID)
87#endif
88 {
89 Assert(pMipmapLevel->cbSurface);
90 Assert(pMipmapLevel->cbSurface == pMipmapLevel->cbSurfacePitch * pMipmapLevel->size.height); /* correct for depth stuff? */
91
92 /*
93 * Make sure we've got surface memory buffer.
94 */
95 uint8_t *pbDst = (uint8_t *)pMipmapLevel->pSurfaceData;
96 if (!pbDst)
97 {
98 pMipmapLevel->pSurfaceData = pbDst = (uint8_t *)RTMemAllocZ(pMipmapLevel->cbSurface);
99 AssertReturn(pbDst, VERR_NO_MEMORY);
100 }
101
102#ifdef VMSVGA3D_DIRECT3D
103 /*
104 * D3D specifics.
105 */
106 HRESULT hr;
107 switch (fSwitchFlags)
108 {
109 case SVGA3D_SURFACE_HINT_TEXTURE:
110 case SVGA3D_SURFACE_HINT_RENDERTARGET:
111 case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
112 {
113 /*
114 * Lock the buffer and make it accessible to memcpy.
115 */
116 D3DLOCKED_RECT LockedRect;
117 if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE)
118 {
119 if (pSurface->bounce.pTexture)
120 {
121 if ( !pSurface->fDirty
122 && fSwitchFlags == (SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET)
123 && i == 0 /* only the first time */)
124 {
125 /** @todo stricter checks for associated context */
126 uint32_t cid = pSurface->idAssociatedContext;
127 if ( cid >= pState->cContexts
128 || pState->papContexts[cid]->id != cid)
129 {
130 Log(("vmsvga3dSurfaceUpdateHeapBuffers: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
131 AssertFailedReturn(VERR_INVALID_PARAMETER);
132 }
133 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
134
135 IDirect3DSurface9 *pDst = NULL;
136 hr = pSurface->bounce.pTexture->GetSurfaceLevel(i, &pDst);
137 AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR);
138
139 IDirect3DSurface9 *pSrc = NULL;
140 hr = pSurface->u.pTexture->GetSurfaceLevel(i, &pSrc);
141 AssertMsgReturn(hr == D3D_OK, ("GetSurfaceLevel failed with %#x\n", hr), VERR_INTERNAL_ERROR);
142
143 hr = pContext->pDevice->GetRenderTargetData(pSrc, pDst);
144 AssertMsgReturn(hr == D3D_OK, ("GetRenderTargetData failed with %#x\n", hr), VERR_INTERNAL_ERROR);
145
146 pSrc->Release();
147 pDst->Release();
148 }
149
150 hr = pSurface->bounce.pTexture->LockRect(i, /* texture level */
151 &LockedRect,
152 NULL,
153 D3DLOCK_READONLY);
154 }
155 else
156 hr = pSurface->u.pTexture->LockRect(i, /* texture level */
157 &LockedRect,
158 NULL,
159 D3DLOCK_READONLY);
160 }
161 else
162 hr = pSurface->u.pSurface->LockRect(&LockedRect,
163 NULL,
164 D3DLOCK_READONLY);
165 AssertMsgReturn(hr == D3D_OK, ("LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
166
167 /*
168 * Copy the data. Take care in case the pitch differs.
169 */
170 if (pMipmapLevel->cbSurfacePitch == (uint32_t)LockedRect.Pitch)
171 memcpy(pbDst, LockedRect.pBits, pMipmapLevel->cbSurface);
172 else
173 for (uint32_t j = 0; j < pMipmapLevel->size.height; j++)
174 memcpy(pbDst + j * pMipmapLevel->cbSurfacePitch,
175 (uint8_t *)LockedRect.pBits + j * LockedRect.Pitch,
176 pMipmapLevel->cbSurfacePitch);
177
178 /*
179 * Release the buffer.
180 */
181 if (fSwitchFlags & SVGA3D_SURFACE_HINT_TEXTURE)
182 {
183 if (pSurface->bounce.pTexture)
184 {
185 hr = pSurface->bounce.pTexture->UnlockRect(i);
186 AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR);
187 }
188 else
189 hr = pSurface->u.pTexture->UnlockRect(i);
190 }
191 else
192 hr = pSurface->u.pSurface->UnlockRect();
193 AssertMsgReturn(hr == D3D_OK, ("UnlockRect failed with %#x\n", hr), VERR_INTERNAL_ERROR);
194 break;
195 }
196
197 case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
198 {
199 void *pvD3DData = NULL;
200 hr = pSurface->u.pVertexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY);
201 AssertMsgReturn(hr == D3D_OK, ("Lock vertex failed with %x\n", hr), VERR_INTERNAL_ERROR);
202
203 memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface);
204
205 hr = pSurface->u.pVertexBuffer->Unlock();
206 AssertMsg(hr == D3D_OK, ("Unlock vertex failed with %x\n", hr));
207 break;
208 }
209
210 case SVGA3D_SURFACE_HINT_INDEXBUFFER:
211 {
212 void *pvD3DData = NULL;
213 hr = pSurface->u.pIndexBuffer->Lock(0, 0, &pvD3DData, D3DLOCK_READONLY);
214 AssertMsgReturn(hr == D3D_OK, ("Lock index failed with %x\n", hr), VERR_INTERNAL_ERROR);
215
216 memcpy(pbDst, pvD3DData, pMipmapLevel->cbSurface);
217
218 hr = pSurface->u.pIndexBuffer->Unlock();
219 AssertMsg(hr == D3D_OK, ("Unlock index failed with %x\n", hr));
220 break;
221 }
222
223 default:
224 AssertMsgFailed(("%#x\n", fSwitchFlags));
225 }
226
227#elif defined(VMSVGA3D_OPENGL)
228 /*
229 * OpenGL specifics.
230 */
231 switch (fSwitchFlags)
232 {
233 case SVGA3D_SURFACE_HINT_TEXTURE:
234 case SVGA3D_SURFACE_HINT_RENDERTARGET:
235 case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
236 {
237 GLint activeTexture;
238 glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
239 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
240
241 glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
242 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
243
244 /* Set row length and alignment of the output data. */
245 VMSVGAPACKPARAMS SavedParams;
246 vmsvga3dSetPackParams(pState, pContext, pSurface, &SavedParams);
247
248 glGetTexImage(GL_TEXTURE_2D,
249 i,
250 pSurface->formatGL,
251 pSurface->typeGL,
252 pbDst);
253 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
254
255 vmsvga3dRestorePackParams(pState, pContext, pSurface, &SavedParams);
256
257 /* Restore the old active texture. */
258 glBindTexture(GL_TEXTURE_2D, activeTexture);
259 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
260 break;
261 }
262
263 case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
264 case SVGA3D_SURFACE_HINT_INDEXBUFFER:
265 {
266 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer);
267 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
268
269 void *pvSrc = pState->ext.glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
270 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
271 if (RT_VALID_PTR(pvSrc))
272 memcpy(pbDst, pvSrc, pMipmapLevel->cbSurface);
273 else
274 AssertPtr(pvSrc);
275
276 pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);
277 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
278
279 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0);
280 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
281 break;
282 }
283
284 default:
285 AssertMsgFailed(("%#x\n", fSwitchFlags));
286 }
287#else
288# error "misconfigured"
289#endif
290 }
291 /* else: There is no data in hardware yet, so whatever we got is already current. */
292 }
293 }
294 }
295
296 return VINF_SUCCESS;
297}
298
299
300/**
301 * Updates the heap buffers for all surfaces or one specific one.
302 *
303 * @param pThis The VGA device instance data.
304 * @param sid The surface ID, UINT32_MAX if all.
305 * @thread VMSVGAFIFO
306 */
307void vmsvga3dUpdateHeapBuffersForSurfaces(PVGASTATE pThis, uint32_t sid)
308{
309 PVMSVGA3DSTATE pState = pThis->svga.p3dState;
310 AssertReturnVoid(pState);
311
312 if (sid == UINT32_MAX)
313 {
314 uint32_t cSurfaces = pState->cSurfaces;
315 for (sid = 0; sid < cSurfaces; sid++)
316 {
317 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
318 if (pSurface && pSurface->id == sid)
319 vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface);
320 }
321 }
322 else if (sid < pState->cSurfaces)
323 {
324 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
325 if (pSurface && pSurface->id == sid)
326 vmsvga3dSurfaceUpdateHeapBuffers(pState, pSurface);
327 }
328}
329
330
331int vmsvga3dLoadExec(PVGASTATE pThis, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
332{
333 PVMSVGA3DSTATE pState = pThis->svga.p3dState;
334 AssertReturn(pState, VERR_NO_MEMORY);
335 int rc;
336 uint32_t cContexts, cSurfaces;
337
338 /* Must initialize now as the recreation calls below rely on an initialized 3d subsystem. */
339 vmsvga3dPowerOn(pThis);
340
341 /* Get the generic 3d state first. */
342 rc = SSMR3GetStructEx(pSSM, pState, sizeof(*pState), 0, g_aVMSVGA3DSTATEFields, NULL);
343 AssertRCReturn(rc, rc);
344
345 cContexts = pState->cContexts;
346 cSurfaces = pState->cSurfaces;
347 pState->cContexts = 0;
348 pState->cSurfaces = 0;
349
350 /* Fetch all active contexts. */
351 for (uint32_t i = 0; i < cContexts; i++)
352 {
353 PVMSVGA3DCONTEXT pContext;
354 uint32_t cid;
355
356 /* Get the context id */
357 rc = SSMR3GetU32(pSSM, &cid);
358 AssertRCReturn(rc, rc);
359
360 if (cid != SVGA3D_INVALID_ID)
361 {
362 uint32_t cPixelShaderConst, cVertexShaderConst, cPixelShaders, cVertexShaders;
363
364 rc = vmsvga3dContextDefine(pThis, cid);
365 AssertRCReturn(rc, rc);
366
367 pContext = pState->papContexts[i];
368 AssertReturn(pContext->id == cid, VERR_INTERNAL_ERROR);
369
370 rc = SSMR3GetStructEx(pSSM, pContext, sizeof(*pContext), 0, g_aVMSVGA3DCONTEXTFields, NULL);
371 AssertRCReturn(rc, rc);
372
373 cPixelShaders = pContext->cPixelShaders;
374 cVertexShaders = pContext->cVertexShaders;
375 cPixelShaderConst = pContext->state.cPixelShaderConst;
376 cVertexShaderConst = pContext->state.cVertexShaderConst;
377 pContext->cPixelShaders = 0;
378 pContext->cVertexShaders = 0;
379 pContext->state.cPixelShaderConst = 0;
380 pContext->state.cVertexShaderConst = 0;
381
382 /* Fetch all pixel shaders. */
383 for (uint32_t j = 0; j < cPixelShaders; j++)
384 {
385 VMSVGA3DSHADER shader;
386 uint32_t shid;
387
388 /* Fetch the id first. */
389 rc = SSMR3GetU32(pSSM, &shid);
390 AssertRCReturn(rc, rc);
391
392 if (shid != SVGA3D_INVALID_ID)
393 {
394 uint32_t *pData;
395
396 /* Fetch a copy of the shader struct. */
397 rc = SSMR3GetStructEx(pSSM, &shader, sizeof(shader), 0, g_aVMSVGA3DSHADERFields, NULL);
398 AssertRCReturn(rc, rc);
399
400 pData = (uint32_t *)RTMemAlloc(shader.cbData);
401 AssertReturn(pData, VERR_NO_MEMORY);
402
403 rc = SSMR3GetMem(pSSM, pData, shader.cbData);
404 AssertRCReturn(rc, rc);
405
406 rc = vmsvga3dShaderDefine(pThis, cid, shid, shader.type, shader.cbData, pData);
407 AssertRCReturn(rc, rc);
408
409 RTMemFree(pData);
410 }
411 }
412
413 /* Fetch all vertex shaders. */
414 for (uint32_t j = 0; j < cVertexShaders; j++)
415 {
416 VMSVGA3DSHADER shader;
417 uint32_t shid;
418
419 /* Fetch the id first. */
420 rc = SSMR3GetU32(pSSM, &shid);
421 AssertRCReturn(rc, rc);
422
423 if (shid != SVGA3D_INVALID_ID)
424 {
425 uint32_t *pData;
426
427 /* Fetch a copy of the shader struct. */
428 rc = SSMR3GetStructEx(pSSM, &shader, sizeof(shader), 0, g_aVMSVGA3DSHADERFields, NULL);
429 AssertRCReturn(rc, rc);
430
431 pData = (uint32_t *)RTMemAlloc(shader.cbData);
432 AssertReturn(pData, VERR_NO_MEMORY);
433
434 rc = SSMR3GetMem(pSSM, pData, shader.cbData);
435 AssertRCReturn(rc, rc);
436
437 rc = vmsvga3dShaderDefine(pThis, cid, shid, shader.type, shader.cbData, pData);
438 AssertRCReturn(rc, rc);
439
440 RTMemFree(pData);
441 }
442 }
443
444 /* Fetch pixel shader constants. */
445 for (uint32_t j = 0; j < cPixelShaderConst; j++)
446 {
447 VMSVGASHADERCONST ShaderConst;
448
449 rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
450 AssertRCReturn(rc, rc);
451
452 if (ShaderConst.fValid)
453 {
454 rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_PS, ShaderConst.ctype, 1, ShaderConst.value);
455 AssertRCReturn(rc, rc);
456 }
457 }
458
459 /* Fetch vertex shader constants. */
460 for (uint32_t j = 0; j < cVertexShaderConst; j++)
461 {
462 VMSVGASHADERCONST ShaderConst;
463
464 rc = SSMR3GetStructEx(pSSM, &ShaderConst, sizeof(ShaderConst), 0, g_aVMSVGASHADERCONSTFields, NULL);
465 AssertRCReturn(rc, rc);
466
467 if (ShaderConst.fValid)
468 {
469 rc = vmsvga3dShaderSetConst(pThis, cid, j, SVGA3D_SHADERTYPE_VS, ShaderConst.ctype, 1, ShaderConst.value);
470 AssertRCReturn(rc, rc);
471 }
472 }
473
474 }
475 }
476
477 /* Fetch all surfaces. */
478 for (uint32_t i = 0; i < cSurfaces; i++)
479 {
480 uint32_t sid;
481
482 /* Fetch the id first. */
483 rc = SSMR3GetU32(pSSM, &sid);
484 AssertRCReturn(rc, rc);
485
486 if (sid != SVGA3D_INVALID_ID)
487 {
488 VMSVGA3DSURFACE surface;
489
490 /* Fetch the surface structure first. */
491 rc = SSMR3GetStructEx(pSSM, &surface, sizeof(surface), 0, g_aVMSVGA3DSURFACEFields, NULL);
492 AssertRCReturn(rc, rc);
493
494 {
495 uint32_t cMipLevels = surface.faces[0].numMipLevels * surface.cFaces;
496 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = (PVMSVGA3DMIPMAPLEVEL)RTMemAlloc(cMipLevels * sizeof(VMSVGA3DMIPMAPLEVEL));
497 AssertReturn(pMipmapLevel, VERR_NO_MEMORY);
498 SVGA3dSize *pMipmapLevelSize = (SVGA3dSize *)RTMemAlloc(cMipLevels * sizeof(SVGA3dSize));
499 AssertReturn(pMipmapLevelSize, VERR_NO_MEMORY);
500
501 /* Load the mip map level info. */
502 for (uint32_t face=0; face < surface.cFaces; face++)
503 {
504 for (uint32_t j = 0; j < surface.faces[0].numMipLevels; j++)
505 {
506 uint32_t idx = j + face * surface.faces[0].numMipLevels;
507 /* Load the mip map level struct. */
508 rc = SSMR3GetStructEx(pSSM, &pMipmapLevel[idx], sizeof(pMipmapLevel[idx]), 0, g_aVMSVGA3DMIPMAPLEVELFields, NULL);
509 AssertRCReturn(rc, rc);
510
511 pMipmapLevelSize[idx] = pMipmapLevel[idx].size;
512 }
513 }
514
515 rc = vmsvga3dSurfaceDefine(pThis, sid, surface.flags, surface.format, surface.faces, surface.multiSampleCount, surface.autogenFilter, cMipLevels, pMipmapLevelSize);
516 AssertRCReturn(rc, rc);
517
518 RTMemFree(pMipmapLevelSize);
519 RTMemFree(pMipmapLevel);
520 }
521
522 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
523 Assert(pSurface->id == sid);
524
525 pSurface->fDirty = false;
526
527 /* Load the mip map level data. */
528 for (uint32_t j = 0; j < pSurface->faces[0].numMipLevels * pSurface->cFaces; j++)
529 {
530 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[j];
531 bool fDataPresent = false;
532
533 Assert(pMipmapLevel->cbSurface);
534 pMipmapLevel->pSurfaceData = RTMemAllocZ(pMipmapLevel->cbSurface);
535 AssertReturn(pMipmapLevel->pSurfaceData, VERR_NO_MEMORY);
536
537 /* Fetch the data present boolean first. */
538 rc = SSMR3GetBool(pSSM, &fDataPresent);
539 AssertRCReturn(rc, rc);
540
541 Log(("Surface sid=%x: load mipmap level %d with %x bytes data (present=%d).\n", sid, j, pMipmapLevel->cbSurface, fDataPresent));
542
543 if (fDataPresent)
544 {
545 rc = SSMR3GetMem(pSSM, pMipmapLevel->pSurfaceData, pMipmapLevel->cbSurface);
546 AssertRCReturn(rc, rc);
547 pMipmapLevel->fDirty = true;
548 pSurface->fDirty = true;
549 }
550 else
551 {
552 pMipmapLevel->fDirty = false;
553 }
554 }
555 }
556 }
557
558 /* Reinitialize all active contexts. */
559 for (uint32_t i = 0; i < pState->cContexts; i++)
560 {
561 PVMSVGA3DCONTEXT pContext = pState->papContexts[i];
562 uint32_t cid = pContext->id;
563
564 if (cid != SVGA3D_INVALID_ID)
565 {
566 /* First set the render targets as they change the internal state (reset viewport etc) */
567 Log(("vmsvga3dLoadExec: Recreate render targets BEGIN\n"));
568 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aRenderTargets); j++)
569 {
570 if (pContext->state.aRenderTargets[j] != SVGA3D_INVALID_ID)
571 {
572 SVGA3dSurfaceImageId target;
573
574 target.sid = pContext->state.aRenderTargets[j];
575 target.face = 0;
576 target.mipmap = 0;
577 rc = vmsvga3dSetRenderTarget(pThis, cid, (SVGA3dRenderTargetType)j, target);
578 AssertRCReturn(rc, rc);
579 }
580 }
581 Log(("vmsvga3dLoadExec: Recreate render targets END\n"));
582
583 /* Recreate the render state */
584 Log(("vmsvga3dLoadExec: Recreate render state BEGIN\n"));
585 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aRenderState); j++)
586 {
587 SVGA3dRenderState *pRenderState = &pContext->state.aRenderState[j];
588
589 if (pRenderState->state != SVGA3D_RS_INVALID)
590 vmsvga3dSetRenderState(pThis, pContext->id, 1, pRenderState);
591 }
592 Log(("vmsvga3dLoadExec: Recreate render state END\n"));
593
594 /* Recreate the texture state */
595 Log(("vmsvga3dLoadExec: Recreate texture state BEGIN\n"));
596 for (uint32_t iStage = 0; iStage < SVGA3D_MAX_TEXTURE_STAGE; iStage++)
597 {
598 for (uint32_t j = 0; j < SVGA3D_TS_MAX; j++)
599 {
600 SVGA3dTextureState *pTextureState = &pContext->state.aTextureState[iStage][j];
601
602 if (pTextureState->name != SVGA3D_TS_INVALID)
603 vmsvga3dSetTextureState(pThis, pContext->id, 1, pTextureState);
604 }
605 }
606 Log(("vmsvga3dLoadExec: Recreate texture state END\n"));
607
608 /* Reprogram the clip planes. */
609 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aClipPlane); j++)
610 {
611 if (pContext->state.aClipPlane[j].fValid == true)
612 vmsvga3dSetClipPlane(pThis, cid, j, pContext->state.aClipPlane[j].plane);
613 }
614
615 /* Reprogram the light data. */
616 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aLightData); j++)
617 {
618 if (pContext->state.aLightData[j].fValidData == true)
619 vmsvga3dSetLightData(pThis, cid, j, &pContext->state.aLightData[j].data);
620 if (pContext->state.aLightData[j].fEnabled)
621 vmsvga3dSetLightEnabled(pThis, cid, j, true);
622 }
623
624 /* Recreate the transform state. */
625 if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_TRANSFORM)
626 {
627 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTransformState); j++)
628 {
629 if (pContext->state.aTransformState[j].fValid == true)
630 vmsvga3dSetTransform(pThis, cid, (SVGA3dTransformType)j, pContext->state.aTransformState[j].matrix);
631 }
632 }
633
634 /* Reprogram the material data. */
635 if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_MATERIAL)
636 {
637 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aMaterial); j++)
638 {
639 if (pContext->state.aMaterial[j].fValid == true)
640 vmsvga3dSetMaterial(pThis, cid, (SVGA3dFace)j, &pContext->state.aMaterial[j].material);
641 }
642 }
643
644 if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_SCISSORRECT)
645 vmsvga3dSetScissorRect(pThis, cid, &pContext->state.RectScissor);
646 if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_ZRANGE)
647 vmsvga3dSetZRange(pThis, cid, pContext->state.zRange);
648 if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_VIEWPORT)
649 vmsvga3dSetViewPort(pThis, cid, &pContext->state.RectViewPort);
650 if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_VERTEXSHADER)
651 vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_VS, pContext->state.shidVertex);
652 if (pContext->state.u32UpdateFlags & VMSVGA3D_UPDATE_PIXELSHADER)
653 vmsvga3dShaderSet(pThis, pContext, cid, SVGA3D_SHADERTYPE_PS, pContext->state.shidPixel);
654 }
655 }
656 return VINF_SUCCESS;
657}
658
659int vmsvga3dSaveExec(PVGASTATE pThis, PSSMHANDLE pSSM)
660{
661 PVMSVGA3DSTATE pState = pThis->svga.p3dState;
662 AssertReturn(pState, VERR_NO_MEMORY);
663 int rc;
664
665 /* Save a copy of the generic 3d state first. */
666 rc = SSMR3PutStructEx(pSSM, pState, sizeof(*pState), 0, g_aVMSVGA3DSTATEFields, NULL);
667 AssertRCReturn(rc, rc);
668
669 /* Save all active contexts. */
670 for (uint32_t i = 0; i < pState->cContexts; i++)
671 {
672 PVMSVGA3DCONTEXT pContext = pState->papContexts[i];
673 uint32_t cid = pContext->id;
674
675 /* Save the id first. */
676 rc = SSMR3PutU32(pSSM, cid);
677 AssertRCReturn(rc, rc);
678
679 if (cid != SVGA3D_INVALID_ID)
680 {
681 /* Save a copy of the context structure first. */
682 rc = SSMR3PutStructEx(pSSM, pContext, sizeof(*pContext), 0, g_aVMSVGA3DCONTEXTFields, NULL);
683 AssertRCReturn(rc, rc);
684
685 /* Save all pixel shaders. */
686 for (uint32_t j = 0; j < pContext->cPixelShaders; j++)
687 {
688 PVMSVGA3DSHADER pShader = &pContext->paPixelShader[j];
689
690 /* Save the id first. */
691 rc = SSMR3PutU32(pSSM, pShader->id);
692 AssertRCReturn(rc, rc);
693
694 if (pShader->id != SVGA3D_INVALID_ID)
695 {
696 uint32_t cbData = pShader->cbData;
697
698 /* Save a copy of the shader struct. */
699 rc = SSMR3PutStructEx(pSSM, pShader, sizeof(*pShader), 0, g_aVMSVGA3DSHADERFields, NULL);
700 AssertRCReturn(rc, rc);
701
702 Log(("Save pixelshader shid=%d with %x bytes code.\n", pShader->id, cbData));
703 rc = SSMR3PutMem(pSSM, pShader->pShaderProgram, cbData);
704 AssertRCReturn(rc, rc);
705 }
706 }
707
708 /* Save all vertex shaders. */
709 for (uint32_t j = 0; j < pContext->cVertexShaders; j++)
710 {
711 PVMSVGA3DSHADER pShader = &pContext->paVertexShader[j];
712
713 /* Save the id first. */
714 rc = SSMR3PutU32(pSSM, pShader->id);
715 AssertRCReturn(rc, rc);
716
717 if (pShader->id != SVGA3D_INVALID_ID)
718 {
719 uint32_t cbData = pShader->cbData;
720
721 /* Save a copy of the shader struct. */
722 rc = SSMR3PutStructEx(pSSM, pShader, sizeof(*pShader), 0, g_aVMSVGA3DSHADERFields, NULL);
723 AssertRCReturn(rc, rc);
724
725 Log(("Save vertex shader shid=%d with %x bytes code.\n", pShader->id, cbData));
726 /* Fetch the shader code and save it. */
727 rc = SSMR3PutMem(pSSM, pShader->pShaderProgram, cbData);
728 AssertRCReturn(rc, rc);
729 }
730 }
731
732 /* Save pixel shader constants. */
733 for (uint32_t j = 0; j < pContext->state.cPixelShaderConst; j++)
734 {
735 rc = SSMR3PutStructEx(pSSM, &pContext->state.paPixelShaderConst[j], sizeof(pContext->state.paPixelShaderConst[j]), 0, g_aVMSVGASHADERCONSTFields, NULL);
736 AssertRCReturn(rc, rc);
737 }
738
739 /* Save vertex shader constants. */
740 for (uint32_t j = 0; j < pContext->state.cVertexShaderConst; j++)
741 {
742 rc = SSMR3PutStructEx(pSSM, &pContext->state.paVertexShaderConst[j], sizeof(pContext->state.paVertexShaderConst[j]), 0, g_aVMSVGASHADERCONSTFields, NULL);
743 AssertRCReturn(rc, rc);
744 }
745 }
746 }
747
748 /* Save all active surfaces. */
749 for (uint32_t sid = 0; sid < pState->cSurfaces; sid++)
750 {
751 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
752
753 /* Save the id first. */
754 rc = SSMR3PutU32(pSSM, pSurface->id);
755 AssertRCReturn(rc, rc);
756
757 if (pSurface->id != SVGA3D_INVALID_ID)
758 {
759 /* Save a copy of the surface structure first. */
760 rc = SSMR3PutStructEx(pSSM, pSurface, sizeof(*pSurface), 0, g_aVMSVGA3DSURFACEFields, NULL);
761 AssertRCReturn(rc, rc);
762
763 /* Save the mip map level info. */
764 for (uint32_t face=0; face < pSurface->cFaces; face++)
765 {
766 for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
767 {
768 uint32_t idx = i + face * pSurface->faces[0].numMipLevels;
769 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[idx];
770
771 /* Save a copy of the mip map level struct. */
772 rc = SSMR3PutStructEx(pSSM, pMipmapLevel, sizeof(*pMipmapLevel), 0, g_aVMSVGA3DMIPMAPLEVELFields, NULL);
773 AssertRCReturn(rc, rc);
774 }
775 }
776
777 /* Save the mip map level data. */
778 for (uint32_t face=0; face < pSurface->cFaces; face++)
779 {
780 for (uint32_t i = 0; i < pSurface->faces[0].numMipLevels; i++)
781 {
782 uint32_t idx = i + face * pSurface->faces[0].numMipLevels;
783 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->pMipmapLevels[idx];
784
785 Log(("Surface sid=%d: save mipmap level %d with %x bytes data.\n", sid, i, pMipmapLevel->cbSurface));
786
787#ifdef VMSVGA3D_DIRECT3D
788 if (!pSurface->u.pSurface)
789#else
790 if (pSurface->oglId.texture == OPENGL_INVALID_ID)
791#endif
792 {
793 if (pMipmapLevel->fDirty)
794 {
795 /* Data follows */
796 rc = SSMR3PutBool(pSSM, true);
797 AssertRCReturn(rc, rc);
798
799 Assert(pMipmapLevel->cbSurface);
800 rc = SSMR3PutMem(pSSM, pMipmapLevel->pSurfaceData, pMipmapLevel->cbSurface);
801 AssertRCReturn(rc, rc);
802 }
803 else
804 {
805 /* No data follows */
806 rc = SSMR3PutBool(pSSM, false);
807 AssertRCReturn(rc, rc);
808 }
809 }
810 else
811 {
812#ifdef VMSVGA3D_DIRECT3D
813 void *pData;
814 bool fRenderTargetTexture = false;
815 bool fTexture = false;
816 bool fVertex = false;
817 bool fSkipSave = false;
818 HRESULT hr;
819
820 Assert(pMipmapLevel->cbSurface);
821 pData = RTMemAllocZ(pMipmapLevel->cbSurface);
822 AssertReturn(pData, VERR_NO_MEMORY);
823
824 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))
825 {
826 case SVGA3D_SURFACE_HINT_DEPTHSTENCIL:
827 case SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE:
828 /* @todo unable to easily fetch depth surface data in d3d 9 */
829 fSkipSave = true;
830 break;
831 case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
832 fRenderTargetTexture = true;
833 /* no break */
834 case SVGA3D_SURFACE_HINT_TEXTURE:
835 fTexture = true;
836 /* no break */
837 case SVGA3D_SURFACE_HINT_RENDERTARGET:
838 {
839 D3DLOCKED_RECT LockedRect;
840
841 if (fTexture)
842 {
843 if (pSurface->bounce.pTexture)
844 {
845 if ( !pSurface->fDirty
846 && fRenderTargetTexture
847 && i == 0 /* only the first time */)
848 {
849 IDirect3DSurface9 *pSrc, *pDest;
850
851 /* @todo stricter checks for associated context */
852 uint32_t cid = pSurface->idAssociatedContext;
853 if ( cid >= pState->cContexts
854 || pState->papContexts[cid]->id != cid)
855 {
856 Log(("vmsvga3dSaveExec invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
857 AssertFailedReturn(VERR_INVALID_PARAMETER);
858 }
859 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
860
861 hr = pSurface->bounce.pTexture->GetSurfaceLevel(i, &pDest);
862 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetSurfaceLevel failed with %x\n", hr), VERR_INTERNAL_ERROR);
863
864 hr = pSurface->u.pTexture->GetSurfaceLevel(i, &pSrc);
865 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetSurfaceLevel failed with %x\n", hr), VERR_INTERNAL_ERROR);
866
867 hr = pContext->pDevice->GetRenderTargetData(pSrc, pDest);
868 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: GetRenderTargetData failed with %x\n", hr), VERR_INTERNAL_ERROR);
869
870 pSrc->Release();
871 pDest->Release();
872 }
873
874 hr = pSurface->bounce.pTexture->LockRect(i, /* texture level */
875 &LockedRect,
876 NULL,
877 D3DLOCK_READONLY);
878 }
879 else
880 hr = pSurface->u.pTexture->LockRect(i, /* texture level */
881 &LockedRect,
882 NULL,
883 D3DLOCK_READONLY);
884 }
885 else
886 hr = pSurface->u.pSurface->LockRect(&LockedRect,
887 NULL,
888 D3DLOCK_READONLY);
889 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: LockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
890
891 /* Copy the data one line at a time in case the internal pitch is different. */
892 for (uint32_t j = 0; j < pMipmapLevel->size.height; j++)
893 {
894 memcpy((uint8_t *)pData + j * pMipmapLevel->cbSurfacePitch, (uint8_t *)LockedRect.pBits + j * LockedRect.Pitch, pMipmapLevel->cbSurfacePitch);
895 }
896
897 if (fTexture)
898 {
899 if (pSurface->bounce.pTexture)
900 {
901 hr = pSurface->bounce.pTexture->UnlockRect(i);
902 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: UnlockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
903 }
904 else
905 hr = pSurface->u.pTexture->UnlockRect(i);
906 }
907 else
908 hr = pSurface->u.pSurface->UnlockRect();
909 AssertMsgReturn(hr == D3D_OK, ("vmsvga3dSaveExec: UnlockRect failed with %x\n", hr), VERR_INTERNAL_ERROR);
910 break;
911 }
912
913 case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
914 fVertex = true;
915 /* no break */
916
917 case SVGA3D_SURFACE_HINT_INDEXBUFFER:
918 {
919 uint8_t *pD3DData;
920
921 if (fVertex)
922 hr = pSurface->u.pVertexBuffer->Lock(0, 0, (void **)&pD3DData, D3DLOCK_READONLY);
923 else
924 hr = pSurface->u.pIndexBuffer->Lock(0, 0, (void **)&pD3DData, D3DLOCK_READONLY);
925 AssertMsg(hr == D3D_OK, ("vmsvga3dSaveExec: Lock %s failed with %x\n", (fVertex) ? "vertex" : "index", hr));
926
927 memcpy(pData, pD3DData, pMipmapLevel->cbSurface);
928
929 if (fVertex)
930 hr = pSurface->u.pVertexBuffer->Unlock();
931 else
932 hr = pSurface->u.pIndexBuffer->Unlock();
933 AssertMsg(hr == D3D_OK, ("vmsvga3dSaveExec: Unlock %s failed with %x\n", (fVertex) ? "vertex" : "index", hr));
934 break;
935 }
936
937 default:
938 AssertFailed();
939 break;
940 }
941
942 if (!fSkipSave)
943 {
944 /* Data follows */
945 rc = SSMR3PutBool(pSSM, true);
946 AssertRCReturn(rc, rc);
947
948 /* And write the surface data. */
949 rc = SSMR3PutMem(pSSM, pData, pMipmapLevel->cbSurface);
950 AssertRCReturn(rc, rc);
951 }
952 else
953 {
954 /* No data follows */
955 rc = SSMR3PutBool(pSSM, false);
956 AssertRCReturn(rc, rc);
957 }
958
959 RTMemFree(pData);
960#elif defined(VMSVGA3D_OPENGL)
961 void *pData = NULL;
962
963# ifdef VMSVGA3D_OGL_WITH_SHARED_CTX
964 PVMSVGA3DCONTEXT pContext = &pState->SharedCtx;
965 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
966# else
967 /* @todo stricter checks for associated context */
968 uint32_t cid = pSurface->idAssociatedContext;
969 if ( cid >= pState->cContexts
970 || pState->papContexts[cid]->id != cid)
971 {
972 Log(("vmsvga3dSaveExec: invalid context id (%x - %x)!\n", cid, (cid >= pState->cContexts) ? -1 : pState->papContexts[cid]->id));
973 AssertFailedReturn(VERR_INVALID_PARAMETER);
974 }
975 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
976 VMSVGA3D_SET_CURRENT_CONTEXT(pState, pContext);
977# endif
978
979 Assert(pMipmapLevel->cbSurface);
980
981 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))
982 {
983 default:
984 AssertFailed();
985 /* no break */
986 case SVGA3D_SURFACE_HINT_DEPTHSTENCIL:
987 case SVGA3D_SURFACE_HINT_DEPTHSTENCIL | SVGA3D_SURFACE_HINT_TEXTURE:
988 /* @todo fetch data from the renderbuffer */
989 /* No data follows */
990 rc = SSMR3PutBool(pSSM, false);
991 AssertRCReturn(rc, rc);
992 break;
993
994 case SVGA3D_SURFACE_HINT_TEXTURE | SVGA3D_SURFACE_HINT_RENDERTARGET:
995 case SVGA3D_SURFACE_HINT_TEXTURE:
996 case SVGA3D_SURFACE_HINT_RENDERTARGET:
997 {
998 GLint activeTexture;
999
1000 pData = RTMemAllocZ(pMipmapLevel->cbSurface);
1001 AssertReturn(pData, VERR_NO_MEMORY);
1002
1003 glGetIntegerv(GL_TEXTURE_BINDING_2D, &activeTexture);
1004 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
1005
1006 glBindTexture(GL_TEXTURE_2D, pSurface->oglId.texture);
1007 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
1008
1009 /* Set row length and alignment of the output data. */
1010 VMSVGAPACKPARAMS SavedParams;
1011 vmsvga3dSetPackParams(pState, pContext, pSurface, &SavedParams);
1012
1013 glGetTexImage(GL_TEXTURE_2D,
1014 i,
1015 pSurface->formatGL,
1016 pSurface->typeGL,
1017 pData);
1018 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
1019
1020 vmsvga3dRestorePackParams(pState, pContext, pSurface, &SavedParams);
1021
1022 /* Data follows */
1023 rc = SSMR3PutBool(pSSM, true);
1024 AssertRCReturn(rc, rc);
1025
1026 /* And write the surface data. */
1027 rc = SSMR3PutMem(pSSM, pData, pMipmapLevel->cbSurface);
1028 AssertRCReturn(rc, rc);
1029
1030 /* Restore the old active texture. */
1031 glBindTexture(GL_TEXTURE_2D, activeTexture);
1032 VMSVGA3D_CHECK_LAST_ERROR_WARN(pState, pContext);
1033 break;
1034 }
1035
1036 case SVGA3D_SURFACE_HINT_VERTEXBUFFER:
1037 case SVGA3D_SURFACE_HINT_INDEXBUFFER:
1038 {
1039 uint8_t *pBufferData;
1040
1041 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, pSurface->oglId.buffer);
1042 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
1043
1044 pBufferData = (uint8_t *)pState->ext.glMapBuffer(GL_ARRAY_BUFFER, GL_READ_ONLY);
1045 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
1046 Assert(pBufferData);
1047
1048 /* Data follows */
1049 rc = SSMR3PutBool(pSSM, true);
1050 AssertRCReturn(rc, rc);
1051
1052 /* And write the surface data. */
1053 rc = SSMR3PutMem(pSSM, pBufferData, pMipmapLevel->cbSurface);
1054 AssertRCReturn(rc, rc);
1055
1056 pState->ext.glUnmapBuffer(GL_ARRAY_BUFFER);
1057 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
1058
1059 pState->ext.glBindBuffer(GL_ARRAY_BUFFER, 0);
1060 VMSVGA3D_CHECK_LAST_ERROR(pState, pContext);
1061
1062 }
1063 }
1064 if (pData)
1065 RTMemFree(pData);
1066#else
1067#error "Unexpected 3d backend"
1068#endif
1069 }
1070 }
1071 }
1072 }
1073 }
1074 return VINF_SUCCESS;
1075}
1076
1077static uint32_t vmsvga3dSaveShaderConst(PVMSVGA3DCONTEXT pContext, uint32_t reg, SVGA3dShaderType type, SVGA3dShaderConstType ctype, uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4)
1078{
1079 /* Choose a sane upper limit. */
1080 AssertReturn(reg < _32K, VERR_INVALID_PARAMETER);
1081
1082 if (type == SVGA3D_SHADERTYPE_VS)
1083 {
1084 if (pContext->state.cVertexShaderConst <= reg)
1085 {
1086 pContext->state.paVertexShaderConst = (PVMSVGASHADERCONST)RTMemRealloc(pContext->state.paVertexShaderConst, sizeof(VMSVGASHADERCONST) * (reg + 1));
1087 AssertReturn(pContext->state.paVertexShaderConst, VERR_NO_MEMORY);
1088 for (uint32_t i = pContext->state.cVertexShaderConst; i < reg + 1; i++)
1089 pContext->state.paVertexShaderConst[i].fValid = false;
1090 pContext->state.cVertexShaderConst = reg + 1;
1091 }
1092
1093 pContext->state.paVertexShaderConst[reg].fValid = true;
1094 pContext->state.paVertexShaderConst[reg].ctype = ctype;
1095 pContext->state.paVertexShaderConst[reg].value[0] = val1;
1096 pContext->state.paVertexShaderConst[reg].value[1] = val2;
1097 pContext->state.paVertexShaderConst[reg].value[2] = val3;
1098 pContext->state.paVertexShaderConst[reg].value[3] = val4;
1099 }
1100 else
1101 {
1102 Assert(type == SVGA3D_SHADERTYPE_PS);
1103 if (pContext->state.cPixelShaderConst <= reg)
1104 {
1105 pContext->state.paPixelShaderConst = (PVMSVGASHADERCONST)RTMemRealloc(pContext->state.paPixelShaderConst, sizeof(VMSVGASHADERCONST) * (reg + 1));
1106 AssertReturn(pContext->state.paPixelShaderConst, VERR_NO_MEMORY);
1107 for (uint32_t i = pContext->state.cPixelShaderConst; i < reg + 1; i++)
1108 pContext->state.paPixelShaderConst[i].fValid = false;
1109 pContext->state.cPixelShaderConst = reg + 1;
1110 }
1111
1112 pContext->state.paPixelShaderConst[reg].fValid = true;
1113 pContext->state.paPixelShaderConst[reg].ctype = ctype;
1114 pContext->state.paPixelShaderConst[reg].value[0] = val1;
1115 pContext->state.paPixelShaderConst[reg].value[1] = val2;
1116 pContext->state.paPixelShaderConst[reg].value[2] = val3;
1117 pContext->state.paPixelShaderConst[reg].value[3] = val4;
1118 }
1119
1120 return VINF_SUCCESS;
1121}
1122
1123
1124
1125static const char * const g_apszTransformTypes[] =
1126{
1127 "SVGA3D_TRANSFORM_INVALID",
1128 "SVGA3D_TRANSFORM_WORLD",
1129 "SVGA3D_TRANSFORM_VIEW",
1130 "SVGA3D_TRANSFORM_PROJECTION",
1131 "SVGA3D_TRANSFORM_TEXTURE0",
1132 "SVGA3D_TRANSFORM_TEXTURE1",
1133 "SVGA3D_TRANSFORM_TEXTURE2",
1134 "SVGA3D_TRANSFORM_TEXTURE3",
1135 "SVGA3D_TRANSFORM_TEXTURE4",
1136 "SVGA3D_TRANSFORM_TEXTURE5",
1137 "SVGA3D_TRANSFORM_TEXTURE6",
1138 "SVGA3D_TRANSFORM_TEXTURE7",
1139 "SVGA3D_TRANSFORM_WORLD1",
1140 "SVGA3D_TRANSFORM_WORLD2",
1141 "SVGA3D_TRANSFORM_WORLD3",
1142};
1143
1144static const char * const g_apszFaces[] =
1145{
1146 "SVGA3D_FACE_INVALID",
1147 "SVGA3D_FACE_NONE",
1148 "SVGA3D_FACE_FRONT",
1149 "SVGA3D_FACE_BACK",
1150 "SVGA3D_FACE_FRONT_BACK",
1151};
1152
1153static const char * const g_apszLightTypes[] =
1154{
1155 "SVGA3D_LIGHTTYPE_INVALID",
1156 "SVGA3D_LIGHTTYPE_POINT",
1157 "SVGA3D_LIGHTTYPE_SPOT1",
1158 "SVGA3D_LIGHTTYPE_SPOT2",
1159 "SVGA3D_LIGHTTYPE_DIRECTIONAL",
1160};
1161
1162static const char * const g_apszRenderTargets[] =
1163{
1164 "SVGA3D_RT_DEPTH",
1165 "SVGA3D_RT_STENCIL",
1166 "SVGA3D_RT_COLOR0",
1167 "SVGA3D_RT_COLOR1",
1168 "SVGA3D_RT_COLOR2",
1169 "SVGA3D_RT_COLOR3",
1170 "SVGA3D_RT_COLOR4",
1171 "SVGA3D_RT_COLOR5",
1172 "SVGA3D_RT_COLOR6",
1173 "SVGA3D_RT_COLOR7",
1174};
1175
1176static void vmsvga3dInfoContextWorkerOne(PCDBGFINFOHLP pHlp, PVMSVGA3DCONTEXT pContext, bool fVerbose)
1177{
1178 char szTmp[128];
1179
1180 pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d context %#x (%d) ***\n", pContext->id, pContext->id);
1181#ifdef RT_OS_WINDOWS
1182 pHlp->pfnPrintf(pHlp, "hwnd: %p\n", pContext->hwnd);
1183 if (fVerbose)
1184 vmsvga3dInfoHostWindow(pHlp, (uintptr_t)pContext->hwnd);
1185# ifdef VMSVGA3D_DIRECT3D
1186 pHlp->pfnPrintf(pHlp, "pDevice: %p\n", pContext->pDevice);
1187# else
1188 pHlp->pfnPrintf(pHlp, "hdc: %p\n", pContext->hdc);
1189 pHlp->pfnPrintf(pHlp, "hglrc: %p\n", pContext->hglrc);
1190# endif
1191#else
1192/** @todo Other hosts... */
1193#endif
1194 pHlp->pfnPrintf(pHlp, "sidRenderTarget: %#x\n", pContext->sidRenderTarget);
1195
1196 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->aSidActiveTexture); i++)
1197 if (pContext->aSidActiveTexture[i] != SVGA3D_INVALID_ID)
1198 pHlp->pfnPrintf(pHlp, "aSidActiveTexture[%u]: %#x\n", i, pContext->aSidActiveTexture[i]);
1199
1200 pHlp->pfnPrintf(pHlp, "fUpdateFlags: %#x\n", pContext->state.u32UpdateFlags);
1201
1202 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderState); i++)
1203 if (pContext->state.aRenderState[i].state != SVGA3D_RS_INVALID)
1204 pHlp->pfnPrintf(pHlp, "aRenderState[%3d]: %s\n", i,
1205 vmsvga3dFormatRenderState(szTmp, sizeof(szTmp), &pContext->state.aRenderState[i]));
1206
1207 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTextureState); i++)
1208 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTextureState[i]); j++)
1209 if (pContext->state.aTextureState[i][j].name != SVGA3D_TS_INVALID)
1210 pHlp->pfnPrintf(pHlp, "aTextureState[%3d][%3d]: %s\n", i, j,
1211 vmsvga3dFormatTextureState(szTmp, sizeof(szTmp), &pContext->state.aTextureState[i][j]));
1212
1213 AssertCompile(RT_ELEMENTS(g_apszTransformTypes) == SVGA3D_TRANSFORM_MAX);
1214 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aTransformState); i++)
1215 if (pContext->state.aTransformState[i].fValid)
1216 {
1217 pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]:\n", g_apszTransformTypes[i], i);
1218 for (uint32_t j = 0; j < RT_ELEMENTS(pContext->state.aTransformState[i].matrix); j++)
1219 pHlp->pfnPrintf(pHlp,
1220 (j % 4) == 0 ? " [ " FLOAT_FMT_STR : (j % 4) < 3 ? ", " FLOAT_FMT_STR : ", " FLOAT_FMT_STR "]\n",
1221 FLOAT_FMT_ARGS(pContext->state.aTransformState[i].matrix[j]));
1222 }
1223
1224 AssertCompile(RT_ELEMENTS(g_apszFaces) == SVGA3D_FACE_MAX);
1225 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aMaterial); i++)
1226 if (pContext->state.aMaterial[i].fValid)
1227 {
1228 pHlp->pfnPrintf(pHlp, "aTransformState[%s(%u)]: shininess=" FLOAT_FMT_STR "\n",
1229 g_apszFaces[i], i, FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.shininess));
1230 pHlp->pfnPrintf(pHlp, " diffuse =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1231 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[0]),
1232 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[1]),
1233 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[2]),
1234 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.diffuse[3]));
1235 pHlp->pfnPrintf(pHlp, " ambient =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1236 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[0]),
1237 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[1]),
1238 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[2]),
1239 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.ambient[3]));
1240 pHlp->pfnPrintf(pHlp, " specular=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1241 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[0]),
1242 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[1]),
1243 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[2]),
1244 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.specular[3]));
1245 pHlp->pfnPrintf(pHlp, " emissive=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1246 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[0]),
1247 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[1]),
1248 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[2]),
1249 FLOAT_FMT_ARGS(pContext->state.aMaterial[i].material.emissive[3]));
1250 }
1251
1252 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aClipPlane); i++)
1253 if (pContext->state.aClipPlane[i].fValid)
1254 pHlp->pfnPrintf(pHlp, "aClipPlane[%#04x]: [ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1255 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[0]),
1256 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[1]),
1257 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[2]),
1258 FLOAT_FMT_ARGS(pContext->state.aClipPlane[i].plane[3]));
1259
1260 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aLightData); i++)
1261 if (pContext->state.aLightData[i].fValidData)
1262 {
1263 pHlp->pfnPrintf(pHlp, "aLightData[%#04x]: enabled=%RTbool inWorldSpace=%RTbool type=%s(%u)\n",
1264 i,
1265 pContext->state.aLightData[i].fEnabled,
1266 pContext->state.aLightData[i].data.inWorldSpace,
1267 (uint32_t)pContext->state.aLightData[i].data.type < RT_ELEMENTS(g_apszLightTypes)
1268 ? g_apszLightTypes[pContext->state.aLightData[i].data.type] : "UNKNOWN",
1269 pContext->state.aLightData[i].data.type);
1270 pHlp->pfnPrintf(pHlp, " diffuse =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1271 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[0]),
1272 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[1]),
1273 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[2]),
1274 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.diffuse[3]));
1275 pHlp->pfnPrintf(pHlp, " specular =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1276 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[0]),
1277 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[1]),
1278 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[2]),
1279 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.specular[3]));
1280 pHlp->pfnPrintf(pHlp, " ambient =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1281 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[0]),
1282 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[1]),
1283 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[2]),
1284 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.ambient[3]));
1285 pHlp->pfnPrintf(pHlp, " position =[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1286 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[0]),
1287 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[1]),
1288 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[2]),
1289 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.position[3]));
1290 pHlp->pfnPrintf(pHlp, " direction=[ " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR " ]\n",
1291 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[0]),
1292 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[1]),
1293 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[2]),
1294 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.direction[3]));
1295 pHlp->pfnPrintf(pHlp, " range=" FLOAT_FMT_STR " falloff=" FLOAT_FMT_STR "\n",
1296 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.range),
1297 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.falloff));
1298 pHlp->pfnPrintf(pHlp, " attenuation0=" FLOAT_FMT_STR " attenuation1=" FLOAT_FMT_STR " attenuation2=" FLOAT_FMT_STR "\n",
1299 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation0),
1300 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation1),
1301 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.attenuation2));
1302 pHlp->pfnPrintf(pHlp, " theta=" FLOAT_FMT_STR " phi=" FLOAT_FMT_STR "\n",
1303 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.theta),
1304 FLOAT_FMT_ARGS(pContext->state.aLightData[i].data.phi));
1305 }
1306
1307 for (uint32_t i = 0; i < RT_ELEMENTS(pContext->state.aRenderTargets); i++)
1308 if (pContext->state.aRenderTargets[i] != SVGA3D_INVALID_ID)
1309 pHlp->pfnPrintf(pHlp, "aRenderTargets[%s/%u] = %#x (%d)\n",
1310 i < RT_ELEMENTS(g_apszRenderTargets) ? g_apszRenderTargets[i] : "UNKNOWN", i,
1311 pContext->state.aRenderTargets[i], pContext->state.aRenderTargets[i]);
1312
1313 pHlp->pfnPrintf(pHlp, "RectScissor: (x,y,cx,cy)=(%u,%u,%u,%u)\n",
1314 pContext->state.RectViewPort.x, pContext->state.RectViewPort.y,
1315 pContext->state.RectViewPort.w, pContext->state.RectViewPort.h);
1316 pHlp->pfnPrintf(pHlp, "zRange: (min,max)=(" FLOAT_FMT_STR ", " FLOAT_FMT_STR ")\n",
1317 FLOAT_FMT_ARGS(pContext->state.zRange.min),
1318 FLOAT_FMT_ARGS(pContext->state.zRange.max));
1319 pHlp->pfnPrintf(pHlp, "fUpdateFlags: %#x\n", pContext->state.u32UpdateFlags);
1320 pHlp->pfnPrintf(pHlp, "shidPixel: %#x (%d)\n", pContext->state.shidPixel, pContext->state.shidPixel);
1321 pHlp->pfnPrintf(pHlp, "shidVertex: %#x (%d)\n", pContext->state.shidVertex, pContext->state.shidVertex);
1322
1323 for (uint32_t iWhich = 0; iWhich < 2; iWhich++)
1324 {
1325 uint32_t cConsts = iWhich == 0 ? pContext->state.cPixelShaderConst : pContext->state.cVertexShaderConst;
1326 PVMSVGASHADERCONST paConsts = iWhich == 0 ? pContext->state.paPixelShaderConst : pContext->state.paVertexShaderConst;
1327 const char *pszName = iWhich ? "paPixelShaderConst" : "paVertexShaderConst";
1328
1329 for (uint32_t i = 0; i < cConsts; i++)
1330 if (paConsts[i].fValid)
1331 {
1332 if (paConsts[i].ctype == SVGA3D_CONST_TYPE_FLOAT)
1333 pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [" FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR ", " FLOAT_FMT_STR "] ctype=FLOAT\n",
1334 pszName, i, i,
1335 FLOAT_FMT_ARGS(paConsts[i].value[0]), FLOAT_FMT_ARGS(paConsts[i].value[1]),
1336 FLOAT_FMT_ARGS(paConsts[i].value[2]), FLOAT_FMT_ARGS(paConsts[i].value[3]));
1337 else
1338 pHlp->pfnPrintf(pHlp, "%s[%#x(%u)] = [%#x, %#x, %#x, %#x] ctype=%s\n",
1339 pszName, i, i,
1340 paConsts[i].value[0], paConsts[i].value[1],
1341 paConsts[i].value[2], paConsts[i].value[3],
1342 paConsts[i].ctype == SVGA3D_CONST_TYPE_INT ? "INT"
1343 : paConsts[i].ctype == SVGA3D_CONST_TYPE_BOOL ? "BOOL" : "UNKNOWN");
1344 }
1345 }
1346
1347 for (uint32_t iWhich = 0; iWhich < 2; iWhich++)
1348 {
1349 uint32_t cShaders = iWhich == 0 ? pContext->cPixelShaders : pContext->cVertexShaders;
1350 PVMSVGA3DSHADER paShaders = iWhich == 0 ? pContext->paPixelShader : pContext->paVertexShader;
1351 const char *pszName = iWhich == 0 ? "paPixelShaders" : "paVertexShaders";
1352 for (uint32_t i = 0; i < cShaders; i++)
1353 if (paShaders[i].id == i)
1354 {
1355 pHlp->pfnPrintf(pHlp, "%s[%u]: id=%#x cid=%#x type=%s(%d) cbData=%#x pvData=%p\n",
1356 pszName, i,
1357 paShaders[i].id,
1358 paShaders[i].cid,
1359 paShaders[i].type == SVGA3D_SHADERTYPE_VS ? "VS"
1360 : paShaders[i].type == SVGA3D_SHADERTYPE_PS ? "PS" : "UNKNOWN",
1361 paShaders[i].type,
1362 paShaders[i].cbData,
1363 paShaders[i].pShaderProgram);
1364 }
1365 }
1366}
1367
1368
1369void vmsvga3dInfoContextWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t cid, bool fVerbose)
1370{
1371 /* Warning! This code is currently racing papContexts reallocation! */
1372 /* Warning! This code is currently racing papContexts reallocation! */
1373 /* Warning! This code is currently racing papContexts reallocation! */
1374 VMSVGA3DSTATE volatile *pState = pThis->svga.p3dState;
1375 if (pState)
1376 {
1377 /*
1378 * Deal with a specific request first.
1379 */
1380 if (cid != UINT32_MAX)
1381 {
1382 if (cid < pState->cContexts)
1383 {
1384 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
1385 if (pContext && pContext->id == cid)
1386 {
1387 vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);
1388 return;
1389 }
1390 }
1391 pHlp->pfnPrintf(pHlp, "Context ID %#x not found.\n", cid);
1392 }
1393 else
1394 {
1395 /*
1396 * Dump all.
1397 */
1398 uint32_t cContexts = pState->cContexts;
1399 pHlp->pfnPrintf(pHlp, "cContexts=%d\n", cContexts);
1400 for (cid = 0; cid < cContexts; cid++)
1401 {
1402 PVMSVGA3DCONTEXT pContext = pState->papContexts[cid];
1403 if (pContext && pContext->id == cid)
1404 {
1405 pHlp->pfnPrintf(pHlp, "\n");
1406 vmsvga3dInfoContextWorkerOne(pHlp, pContext, fVerbose);
1407 }
1408 }
1409 }
1410 }
1411}
1412
1413/** Values for SVGA3dTextureFilter, prefix SVGA3D_TEX_FILTER_. */
1414static const char * const g_apszTexureFilters[] =
1415{
1416 "NONE",
1417 "NEAREST",
1418 "LINEAR",
1419 "ANISOTROPIC",
1420 "FLATCUBIC",
1421 "GAUSSIANCUBIC",
1422 "PYRAMIDALQUAD",
1423 "GAUSSIANQUAD",
1424};
1425
1426/** SVGA3dSurfaceFlags values, prefix SVGA3D_SURFACE_. */
1427static VMSVGAINFOFLAGS32 const g_aSvga3DSurfaceFlags[] =
1428{
1429 { SVGA3D_SURFACE_CUBEMAP , "CUBEMAP" },
1430 { SVGA3D_SURFACE_HINT_STATIC , "HINT_STATIC" },
1431 { SVGA3D_SURFACE_HINT_DYNAMIC , "HINT_DYNAMIC" },
1432 { SVGA3D_SURFACE_HINT_INDEXBUFFER , "HINT_INDEXBUFFER" },
1433 { SVGA3D_SURFACE_HINT_VERTEXBUFFER , "HINT_VERTEXBUFFER" },
1434 { SVGA3D_SURFACE_HINT_TEXTURE , "HINT_TEXTURE" },
1435 { SVGA3D_SURFACE_HINT_RENDERTARGET , "HINT_RENDERTARGET" },
1436 { SVGA3D_SURFACE_HINT_DEPTHSTENCIL , "HINT_DEPTHSTENCIL" },
1437 { SVGA3D_SURFACE_HINT_WRITEONLY , "HINT_WRITEONLY" },
1438 { SVGA3D_SURFACE_MASKABLE_ANTIALIAS , "MASKABLE_ANTIALIAS" },
1439 { SVGA3D_SURFACE_AUTOGENMIPMAPS , "AUTOGENMIPMAPS" },
1440};
1441
1442
1443#ifdef VMSVGA3D_DIRECT3D
1444
1445/** Values for D3DFORMAT, prefix D3DFMT_. */
1446static VMSVGAINFOENUM const g_aD3DFormats[] =
1447{
1448 { D3DFMT_UNKNOWN , "UNKNOWN" },
1449 { D3DFMT_R8G8B8 , "R8G8B8" },
1450 { D3DFMT_A8R8G8B8 , "A8R8G8B8" },
1451 { D3DFMT_X8R8G8B8 , "X8R8G8B8" },
1452 { D3DFMT_R5G6B5 , "R5G6B5" },
1453 { D3DFMT_X1R5G5B5 , "X1R5G5B5" },
1454 { D3DFMT_A1R5G5B5 , "A1R5G5B5" },
1455 { D3DFMT_A4R4G4B4 , "A4R4G4B4" },
1456 { D3DFMT_R3G3B2 , "R3G3B2" },
1457 { D3DFMT_A8 , "A8" },
1458 { D3DFMT_A8R3G3B2 , "A8R3G3B2" },
1459 { D3DFMT_X4R4G4B4 , "X4R4G4B4" },
1460 { D3DFMT_A2B10G10R10 , "A2B10G10R10" },
1461 { D3DFMT_A8B8G8R8 , "A8B8G8R8" },
1462 { D3DFMT_X8B8G8R8 , "X8B8G8R8" },
1463 { D3DFMT_G16R16 , "G16R16" },
1464 { D3DFMT_A2R10G10B10 , "A2R10G10B10" },
1465 { D3DFMT_A16B16G16R16 , "A16B16G16R16" },
1466 { D3DFMT_A8P8 , "A8P8" },
1467 { D3DFMT_P8 , "P8" },
1468 { D3DFMT_L8 , "L8" },
1469 { D3DFMT_A8L8 , "A8L8" },
1470 { D3DFMT_A4L4 , "A4L4" },
1471 { D3DFMT_V8U8 , "V8U8" },
1472 { D3DFMT_L6V5U5 , "L6V5U5" },
1473 { D3DFMT_X8L8V8U8 , "X8L8V8U8" },
1474 { D3DFMT_Q8W8V8U8 , "Q8W8V8U8" },
1475 { D3DFMT_V16U16 , "V16U16" },
1476 { D3DFMT_A2W10V10U10 , "A2W10V10U10" },
1477 { D3DFMT_D16_LOCKABLE , "D16_LOCKABLE" },
1478 { D3DFMT_D32 , "D32" },
1479 { D3DFMT_D15S1 , "D15S1" },
1480 { D3DFMT_D24S8 , "D24S8" },
1481 { D3DFMT_D24X8 , "D24X8" },
1482 { D3DFMT_D24X4S4 , "D24X4S4" },
1483 { D3DFMT_D16 , "D16" },
1484 { D3DFMT_L16 , "L16" },
1485 { D3DFMT_D32F_LOCKABLE , "D32F_LOCKABLE" },
1486 { D3DFMT_D24FS8 , "D24FS8" },
1487 { D3DFMT_VERTEXDATA , "VERTEXDATA" },
1488 { D3DFMT_INDEX16 , "INDEX16" },
1489 { D3DFMT_INDEX32 , "INDEX32" },
1490 { D3DFMT_Q16W16V16U16 , "Q16W16V16U16" },
1491 { D3DFMT_R16F , "R16F" },
1492 { D3DFMT_G16R16F , "G16R16F" },
1493 { D3DFMT_A16B16G16R16F , "A16B16G16R16F" },
1494 { D3DFMT_R32F , "R32F" },
1495 { D3DFMT_G32R32F , "G32R32F" },
1496 { D3DFMT_A32B32G32R32F , "A32B32G32R32F" },
1497 { D3DFMT_CxV8U8 , "CxV8U8" },
1498 { D3DFMT_UYVY , "UYVY" },
1499 { D3DFMT_YUY2 , "YUY2" },
1500 { D3DFMT_DXT1 , "DXT1" },
1501 { D3DFMT_DXT2 , "DXT2" },
1502 { D3DFMT_DXT3 , "DXT3" },
1503 { D3DFMT_DXT4 , "DXT4" },
1504 { D3DFMT_DXT5 , "DXT5" },
1505 { D3DFMT_MULTI2_ARGB8 , "MULTI2_ARGB8" },
1506 { D3DFMT_G8R8_G8B8 , "G8R8_G8B8" },
1507 { D3DFMT_R8G8_B8G8 , "R8G8_B8G8" },
1508 { D3DFMT_FORCE_DWORD , "FORCE_DWORD" },
1509};
1510
1511/** Values for D3DMULTISAMPLE_TYPE, prefix D3DMULTISAMPLE_. */
1512static VMSVGAINFOENUM const g_aD3DMultiSampleTypes[] =
1513{
1514 { D3DMULTISAMPLE_NONE , "NONE" },
1515 { D3DMULTISAMPLE_NONMASKABLE , "NONMASKABLE" },
1516 { D3DMULTISAMPLE_2_SAMPLES , "2_SAMPLES" },
1517 { D3DMULTISAMPLE_3_SAMPLES , "3_SAMPLES" },
1518 { D3DMULTISAMPLE_4_SAMPLES , "4_SAMPLES" },
1519 { D3DMULTISAMPLE_5_SAMPLES , "5_SAMPLES" },
1520 { D3DMULTISAMPLE_6_SAMPLES , "6_SAMPLES" },
1521 { D3DMULTISAMPLE_7_SAMPLES , "7_SAMPLES" },
1522 { D3DMULTISAMPLE_8_SAMPLES , "8_SAMPLES" },
1523 { D3DMULTISAMPLE_9_SAMPLES , "9_SAMPLES" },
1524 { D3DMULTISAMPLE_10_SAMPLES , "10_SAMPLES" },
1525 { D3DMULTISAMPLE_11_SAMPLES , "11_SAMPLES" },
1526 { D3DMULTISAMPLE_12_SAMPLES , "12_SAMPLES" },
1527 { D3DMULTISAMPLE_13_SAMPLES , "13_SAMPLES" },
1528 { D3DMULTISAMPLE_14_SAMPLES , "14_SAMPLES" },
1529 { D3DMULTISAMPLE_15_SAMPLES , "15_SAMPLES" },
1530 { D3DMULTISAMPLE_16_SAMPLES , "16_SAMPLES" },
1531 { D3DMULTISAMPLE_FORCE_DWORD , "FORCE_DWORD" },
1532};
1533
1534/** D3DUSAGE_XXX flag value, prefix D3DUSAGE_. */
1535static VMSVGAINFOFLAGS32 const g_aD3DUsageFlags[] =
1536{
1537 { D3DUSAGE_RENDERTARGET , "RENDERTARGET" },
1538 { D3DUSAGE_DEPTHSTENCIL , "DEPTHSTENCIL" },
1539 { D3DUSAGE_WRITEONLY , "WRITEONLY" },
1540 { D3DUSAGE_SOFTWAREPROCESSING , "SOFTWAREPROCESSING" },
1541 { D3DUSAGE_DONOTCLIP , "DONOTCLIP" },
1542 { D3DUSAGE_POINTS , "POINTS" },
1543 { D3DUSAGE_RTPATCHES , "RTPATCHES" },
1544 { D3DUSAGE_NPATCHES , "NPATCHES" },
1545 { D3DUSAGE_DYNAMIC , "DYNAMIC" },
1546 { D3DUSAGE_AUTOGENMIPMAP , "AUTOGENMIPMAP" },
1547 { D3DUSAGE_RESTRICTED_CONTENT , "RESTRICTED_CONTENT" },
1548 { D3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER , "RESTRICT_SHARED_RESOURCE_DRIVER" },
1549 { D3DUSAGE_RESTRICT_SHARED_RESOURCE , "RESTRICT_SHARED_RESOURCE" },
1550 { D3DUSAGE_DMAP , "DMAP" },
1551 { D3DUSAGE_NONSECURE , "NONSECURE" },
1552 { D3DUSAGE_TEXTAPI , "TEXTAPI" },
1553};
1554
1555
1556/**
1557 * Release all shared surface objects.
1558 */
1559static DECLCALLBACK(int) vmsvga3dInfoSharedObjectCallback(PAVLU32NODECORE pNode, void *pvUser)
1560{
1561 PVMSVGA3DSHAREDSURFACE pSharedSurface = (PVMSVGA3DSHAREDSURFACE)pNode;
1562 PCDBGFINFOHLP pHlp = (PCDBGFINFOHLP)pvUser;
1563
1564 pHlp->pfnPrintf(pHlp, "Shared surface: %#x pv=%p\n", pSharedSurface->Core.Key, pSharedSurface->u.pCubeTexture);
1565
1566 return 0;
1567}
1568
1569#elif defined(VMSVGA3D_OPENGL)
1570 /** @todo */
1571
1572#else
1573# error "Build config error."
1574#endif
1575
1576
1577static void vmsvga3dInfoSurfaceWorkerOne(PCDBGFINFOHLP pHlp, PVMSVGA3DSURFACE pSurface,
1578 bool fVerbose, uint32_t cxAscii, bool fInvY)
1579{
1580 char szTmp[128];
1581
1582 pHlp->pfnPrintf(pHlp, "*** VMSVGA 3d surface %#x (%d)%s ***\n", pSurface->id, pSurface->id, pSurface->fDirty ? " - dirty" : "");
1583#if defined(VMSVGA3D_OPENGL) && defined(VMSVGA3D_OGL_WITH_SHARED_CTX)
1584 pHlp->pfnPrintf(pHlp, "idWeakContextAssociation: %#x\n", pSurface->idWeakContextAssociation);
1585#else
1586 pHlp->pfnPrintf(pHlp, "idAssociatedContext: %#x\n", pSurface->idAssociatedContext);
1587#endif
1588 pHlp->pfnPrintf(pHlp, "Format: %s\n",
1589 vmsvgaFormatEnumValueEx(szTmp, sizeof(szTmp), NULL, (int)pSurface->format, false, &g_SVGA3dSurfaceFormat2String));
1590 pHlp->pfnPrintf(pHlp, "Flags: %#x", pSurface->flags);
1591 vmsvga3dInfoU32Flags(pHlp, pSurface->flags, "SVGA3D_SURFACE_", g_aSvga3DSurfaceFlags, RT_ELEMENTS(g_aSvga3DSurfaceFlags));
1592 pHlp->pfnPrintf(pHlp, "\n");
1593 if (pSurface->cFaces == 0)
1594 pHlp->pfnPrintf(pHlp, "Faces: %u\n", pSurface->cFaces);
1595 for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
1596 {
1597 Assert(pSurface->faces[iFace].numMipLevels <= pSurface->faces[0].numMipLevels);
1598 if (pSurface->faces[iFace].numMipLevels == 0)
1599 pHlp->pfnPrintf(pHlp, "Faces[%u] Mipmap levels: %u\n", iFace, pSurface->faces[iFace].numMipLevels);
1600
1601 uint32_t iMipmap = iFace * pSurface->faces[0].numMipLevels;
1602 for (uint32_t iLevel = 0; iLevel < pSurface->faces[iFace].numMipLevels; iLevel++, iMipmap++)
1603 {
1604 pHlp->pfnPrintf(pHlp, "Face #%u, mipmap #%u[%u]:%s cx=%u, cy=%u, cz=%u, cbSurface=%#x, cbPitch=%#x",
1605 iFace, iLevel, iMipmap, iMipmap < 10 ? " " : "",
1606 pSurface->pMipmapLevels[iMipmap].size.width,
1607 pSurface->pMipmapLevels[iMipmap].size.height,
1608 pSurface->pMipmapLevels[iMipmap].size.depth,
1609 pSurface->pMipmapLevels[iMipmap].cbSurface,
1610 pSurface->pMipmapLevels[iMipmap].cbSurfacePitch);
1611 if (pSurface->pMipmapLevels[iMipmap].pSurfaceData)
1612 pHlp->pfnPrintf(pHlp, " pvData=%p", pSurface->pMipmapLevels[iMipmap].pSurfaceData);
1613 if (pSurface->pMipmapLevels[iMipmap].fDirty)
1614 pHlp->pfnPrintf(pHlp, " dirty");
1615 pHlp->pfnPrintf(pHlp, "\n");
1616 }
1617 }
1618
1619 pHlp->pfnPrintf(pHlp, "cbBlock: %u (%#x)\n", pSurface->cbBlock, pSurface->cbBlock);
1620 pHlp->pfnPrintf(pHlp, "Multi-sample count: %u\n", pSurface->multiSampleCount);
1621 pHlp->pfnPrintf(pHlp, "Autogen filter: %s\n",
1622 vmsvgaFormatEnumValue(szTmp, sizeof(szTmp), NULL, pSurface->autogenFilter,
1623 "SVGA3D_TEX_FILTER_", g_apszTexureFilters, RT_ELEMENTS(g_apszTexureFilters)));
1624
1625#ifdef VMSVGA3D_DIRECT3D
1626 pHlp->pfnPrintf(pHlp, "formatD3D: %s\n",
1627 vmsvgaFormatEnumValueEx(szTmp, sizeof(szTmp), NULL, pSurface->formatD3D,
1628 "D3DFMT_", g_aD3DFormats, RT_ELEMENTS(g_aD3DFormats)));
1629 pHlp->pfnPrintf(pHlp, "fUsageD3D: %#x", pSurface->fUsageD3D);
1630 vmsvga3dInfoU32Flags(pHlp, pSurface->fUsageD3D, "D3DUSAGE_", g_aD3DUsageFlags, RT_ELEMENTS(g_aD3DUsageFlags));
1631 pHlp->pfnPrintf(pHlp, "\n");
1632 pHlp->pfnPrintf(pHlp, "multiSampleTypeD3D: %s\n",
1633 vmsvgaFormatEnumValueEx(szTmp, sizeof(szTmp), NULL, pSurface->multiSampleTypeD3D,
1634 "D3DMULTISAMPLE", g_aD3DMultiSampleTypes, RT_ELEMENTS(g_aD3DMultiSampleTypes)));
1635 if (pSurface->hSharedObject != NULL)
1636 pHlp->pfnPrintf(pHlp, "hSharedObject: %p\n", pSurface->hSharedObject);
1637 if (pSurface->pQuery)
1638 pHlp->pfnPrintf(pHlp, "pQuery: %p\n", pSurface->pQuery);
1639 if (pSurface->u.pSurface)
1640 pHlp->pfnPrintf(pHlp, "u.pXxxx: %p\n", pSurface->u.pSurface);
1641 if (pSurface->bounce.pTexture)
1642 pHlp->pfnPrintf(pHlp, "bounce.pXxxx: %p\n", pSurface->bounce.pTexture);
1643 RTAvlU32DoWithAll(&pSurface->pSharedObjectTree, true /*fFromLeft*/, vmsvga3dInfoSharedObjectCallback, (void *)pHlp);
1644 pHlp->pfnPrintf(pHlp, "fStencilAsTexture: %RTbool\n", pSurface->fStencilAsTexture);
1645
1646#elif defined(VMSVGA3D_OPENGL)
1647 /** @todo */
1648#else
1649# error "Build config error."
1650#endif
1651
1652 if (fVerbose)
1653 for (uint32_t iFace = 0; iFace < pSurface->cFaces; iFace++)
1654 {
1655 uint32_t iMipmap = iFace * pSurface->faces[0].numMipLevels;
1656 for (uint32_t iLevel = 0; iLevel < pSurface->faces[iFace].numMipLevels; iLevel++, iMipmap++)
1657 if (pSurface->pMipmapLevels[iMipmap].pSurfaceData)
1658 {
1659 if ( ASMMemIsAll8(pSurface->pMipmapLevels[iMipmap].pSurfaceData,
1660 pSurface->pMipmapLevels[iMipmap].cbSurface, 0) == NULL)
1661 pHlp->pfnPrintf(pHlp, "--- Face #%u, mipmap #%u[%u]: all zeros ---\n", iFace, iLevel, iMipmap);
1662 else
1663 {
1664 pHlp->pfnPrintf(pHlp, "--- Face #%u, mipmap #%u[%u]: cx=%u, cy=%u, cz=%u ---\n",
1665 iFace, iLevel, iMipmap,
1666 pSurface->pMipmapLevels[iMipmap].size.width,
1667 pSurface->pMipmapLevels[iMipmap].size.height,
1668 pSurface->pMipmapLevels[iMipmap].size.depth);
1669 vmsvga3dAsciiPrint(vmsvga3dAsciiPrintlnInfo, (void *)pHlp,
1670 pSurface->pMipmapLevels[iMipmap].pSurfaceData,
1671 pSurface->pMipmapLevels[iMipmap].cbSurface,
1672 pSurface->pMipmapLevels[iMipmap].size.width,
1673 pSurface->pMipmapLevels[iMipmap].size.height,
1674 pSurface->pMipmapLevels[iMipmap].cbSurfacePitch,
1675 pSurface->format,
1676 fInvY,
1677 cxAscii, cxAscii * 3 / 4);
1678 }
1679 }
1680 }
1681}
1682
1683
1684void vmsvga3dInfoSurfaceWorker(PVGASTATE pThis, PCDBGFINFOHLP pHlp, uint32_t sid, bool fVerbose, uint32_t cxAscii, bool fInvY)
1685{
1686 /* Warning! This code is currently racing papSurfaces reallocation! */
1687 /* Warning! This code is currently racing papSurfaces reallocation! */
1688 /* Warning! This code is currently racing papSurfaces reallocation! */
1689 VMSVGA3DSTATE volatile *pState = pThis->svga.p3dState;
1690 if (pState)
1691 {
1692 /*
1693 * Deal with a specific request first.
1694 */
1695 if (sid != UINT32_MAX)
1696 {
1697 if (sid < pState->cSurfaces)
1698 {
1699 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
1700 if (pSurface && pSurface->id == sid)
1701 {
1702 if (fVerbose)
1703 vmsvga3dSurfaceUpdateHeapBuffersOnFifoThread(pThis, sid);
1704 vmsvga3dInfoSurfaceWorkerOne(pHlp, pSurface, fVerbose, cxAscii, fInvY);
1705 return;
1706 }
1707 }
1708 pHlp->pfnPrintf(pHlp, "Surface ID %#x not found.\n", sid);
1709 }
1710 else
1711 {
1712 /*
1713 * Dump all.
1714 */
1715 if (fVerbose)
1716 vmsvga3dSurfaceUpdateHeapBuffersOnFifoThread(pThis, UINT32_MAX);
1717 uint32_t cSurfaces = pState->cSurfaces;
1718 pHlp->pfnPrintf(pHlp, "cSurfaces=%d\n", cSurfaces);
1719 for (sid = 0; sid < cSurfaces; sid++)
1720 {
1721 PVMSVGA3DSURFACE pSurface = pState->papSurfaces[sid];
1722 if (pSurface && pSurface->id == sid)
1723 {
1724 pHlp->pfnPrintf(pHlp, "\n");
1725 vmsvga3dInfoSurfaceWorkerOne(pHlp, pSurface, fVerbose, cxAscii, fInvY);
1726 }
1727 }
1728 }
1729 }
1730
1731}
1732
1733
1734#endif /* !___DevVGA_SVGA3d_shared_h___ */
1735
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