VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/DevVGA-SVGA3d-win-dx.cpp@ 86861

Last change on this file since 86861 was 86855, checked in by vboxsync, 4 years ago

Devices/Graphics: Monitor the guest access to ObjectTables; use array of OTables; SVGA3D_DEVCAP logging. bugref:9830

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 43.3 KB
Line 
1/* $Id: DevVGA-SVGA3d-win-dx.cpp 86855 2020-11-11 01:03:54Z vboxsync $ */
2/** @file
3 * DevVMWare - VMWare SVGA device
4 */
5
6/*
7 * Copyright (C) 2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DEV_VMSVGA
23#include <VBox/AssertGuest.h>
24#include <VBox/log.h>
25#include <VBox/vmm/pdmdev.h>
26#include <VBox/vmm/pgm.h>
27
28#include <iprt/assert.h>
29#include <iprt/errcore.h>
30#include <iprt/mem.h>
31
32#include <VBoxVideo.h> /* required by DevVGA.h */
33#include <VBoxVideo3D.h>
34
35/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
36#include "DevVGA.h"
37
38#include "DevVGA-SVGA.h"
39#include "DevVGA-SVGA3d.h"
40#include "DevVGA-SVGA3d-internal.h"
41
42#include <d3d11.h>
43
44
45/* What kind of resource has been created for the VMSVGA3D surface. */
46typedef enum VMSVGA3DBACKRESTYPE
47{
48 VMSVGA3D_RESTYPE_NONE = 0,
49 VMSVGA3D_RESTYPE_SCREEN_TARGET = 1,
50 VMSVGA3D_RESTYPE_SURFACE = 2,
51 VMSVGA3D_RESTYPE_TEXTURE = 3,
52 VMSVGA3D_RESTYPE_CUBE_TEXTURE = 4,
53 VMSVGA3D_RESTYPE_VOLUME_TEXTURE = 5,
54 VMSVGA3D_RESTYPE_VERTEX_BUFFER = 6,
55 VMSVGA3D_RESTYPE_INDEX_BUFFER = 7,
56} VMSVGA3DBACKRESTYPE;
57
58struct VMSVGA3DBACKENDSURFACE
59{
60 VMSVGA3DBACKRESTYPE enmResType;
61 union
62 {
63 struct
64 {
65 ID3D11Texture2D *pTexture; /* The texture for the screen content. */
66 ID3D11Texture2D *pDynamicTexture; /* For screen updates from memory. */ /** @todo One for all screens. */
67 ID3D11Texture2D *pStagingTexture; /* For Reading the screen content. */ /** @todo One for all screens. */
68 } ScreenTarget;
69 struct
70 {
71 } Texture;
72 } u;
73} VMSVGA3DBACKENDSURFACE;
74
75typedef struct VMSVGAHWSCREEN
76{
77 ID3D11Texture2D *pTexture; /* Shared texture for the screen content. Only used as CopyResource target. */
78 IDXGIResource *pDxgiResource; /* Interface of the texture. */
79 IDXGIKeyedMutex *pDXGIKeyedMutex; /* Synchronization interface for the render device. */
80 HANDLE SharedHandle; /* The shared handle of this structure. */
81 uint32_t sidScreenTarget; /* The source surface for this screen. */
82} VMSVGAHWSCREEN;
83
84struct VMSVGA3DBACKEND
85{
86 RTLDRMOD hD3D11;
87 PFN_D3D11_CREATE_DEVICE pfnD3D11CreateDevice;
88
89 ID3D11Device *pDevice; /* Device for the VMSVGA3D context independent operation. */
90 ID3D11DeviceContext *pImmediateContext; /* Corresponding context. */
91 IDXGIFactory *pDxgiFactory; /* DXGI Factory. */
92 D3D_FEATURE_LEVEL FeatureLevel;
93} VMSVGA3DBACKEND;
94
95
96DXGI_FORMAT vmsvgaDXSurfaceFormat2Dxgi(SVGA3dSurfaceFormat format)
97{
98 switch (format)
99 {
100 case SVGA3D_X8R8G8B8: return DXGI_FORMAT_B8G8R8A8_UNORM;
101 default: break;
102 }
103 return DXGI_FORMAT_UNKNOWN;
104}
105
106
107int vmsvga3dInit(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC)
108{
109 RT_NOREF(pDevIns, pThis);
110
111 PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)RTMemAllocZ(sizeof(VMSVGA3DSTATE));
112 AssertReturn(pState, VERR_NO_MEMORY);
113 pThisCC->svga.p3dState = pState;
114
115 PVMSVGA3DBACKEND pBackend = (PVMSVGA3DBACKEND)RTMemAllocZ(sizeof(VMSVGA3DBACKEND));
116 AssertReturn(pBackend, VERR_NO_MEMORY);
117 pState->pBackend = pBackend;
118
119 int rc = RTLdrLoadSystem("d3d11", /* fNoUnload = */ true, &pBackend->hD3D11);
120 AssertRC(rc);
121 if (RT_SUCCESS(rc))
122 {
123 rc = RTLdrGetSymbol(pBackend->hD3D11, "D3D11CreateDevice", (void **)&pBackend->pfnD3D11CreateDevice);
124 AssertRC(rc);
125 }
126
127 return rc;
128}
129
130
131int vmsvga3dPowerOn(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC)
132{
133 RT_NOREF(pDevIns, pThis);
134
135 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
136 AssertReturn(pState, VERR_INVALID_STATE);
137
138 PVMSVGA3DBACKEND pBackend = pState->pBackend;
139 AssertReturn(pBackend, VERR_INVALID_STATE);
140
141 int rc = VINF_SUCCESS;
142
143 IDXGIAdapter *pAdapter = NULL; /* Default adapter. */
144 static D3D_FEATURE_LEVEL const s_aFeatureLevels[] =
145 {
146 /// @todo Requires a Windows 8+ _SDKS: D3D_FEATURE_LEVEL_11_1,
147 D3D_FEATURE_LEVEL_11_0
148 };
149 UINT Flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
150#ifdef DEBUG
151 Flags |= D3D11_CREATE_DEVICE_DEBUG;
152#endif
153
154 HRESULT hr = pBackend->pfnD3D11CreateDevice(pAdapter,
155 D3D_DRIVER_TYPE_HARDWARE,
156 NULL,
157 Flags,
158 s_aFeatureLevels,
159 RT_ELEMENTS(s_aFeatureLevels),
160 D3D11_SDK_VERSION,
161 &pBackend->pDevice,
162 &pBackend->FeatureLevel,
163 &pBackend->pImmediateContext);
164 if (SUCCEEDED(hr))
165 {
166 LogRel(("VMSVGA: Feature level %#x\n", pBackend->FeatureLevel));
167
168 IDXGIDevice *pDxgiDevice = 0;
169 hr = pBackend->pDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&pDxgiDevice);
170 if (SUCCEEDED(hr))
171 {
172 IDXGIAdapter *pDxgiAdapter = 0;
173 hr = pDxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&pDxgiAdapter);
174 if (SUCCEEDED(hr))
175 {
176 hr = pDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&pBackend->pDxgiFactory);
177 D3D_RELEASE(pDxgiAdapter);
178 }
179
180 D3D_RELEASE(pDxgiDevice);
181 }
182 }
183
184 if (FAILED(hr))
185 rc = VERR_NOT_SUPPORTED;
186
187 return rc;
188}
189
190
191int vmsvga3dTerminate(PVGASTATECC pThisCC)
192{
193 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
194 AssertReturn(pState, VERR_INVALID_STATE);
195
196 if (pState->pBackend)
197 {
198 vmsvga3dReset(pThisCC);
199
200 RTMemFree(pState->pBackend);
201 pState->pBackend = NULL;
202 }
203
204 return VINF_SUCCESS;
205}
206
207
208int vmsvga3dReset(PVGASTATECC pThisCC)
209{
210 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
211 AssertReturn(pState, VERR_INVALID_STATE);
212
213 PVMSVGA3DBACKEND pBackend = pState->pBackend;
214 if (pBackend)
215 {
216 D3D_RELEASE(pBackend->pDevice);
217 D3D_RELEASE(pBackend->pImmediateContext);
218 D3D_RELEASE(pBackend->pDxgiFactory);
219 }
220
221 return VINF_SUCCESS;
222}
223
224
225static int vmsvga3dDrvNotifyDefineScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
226{
227 /** @todo Such structures must be in VBoxVideo3D.h */
228 typedef struct VBOX3DNOTIFYDEFINESCREEN
229 {
230 VBOX3DNOTIFY Core;
231 uint32_t cWidth;
232 uint32_t cHeight;
233 int32_t xRoot;
234 int32_t yRoot;
235 uint32_t fPrimary;
236 uint32_t cDpi;
237 } VBOX3DNOTIFYDEFINESCREEN;
238
239 VBOX3DNOTIFYDEFINESCREEN n;
240 n.Core.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_CREATED;
241 n.Core.iDisplay = pScreen->idScreen;
242 n.Core.u32Reserved = 0;
243 n.Core.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
244 RT_ZERO(n.Core.au8Data);
245 n.cWidth = pScreen->cWidth;
246 n.cHeight = pScreen->cHeight;
247 n.xRoot = pScreen->xOrigin;
248 n.yRoot = pScreen->yOrigin;
249 n.fPrimary = RT_BOOL(pScreen->fuScreen & SVGA_SCREEN_IS_PRIMARY);
250 n.cDpi = pScreen->cDpi;
251
252 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n.Core);
253}
254
255
256static int vmsvga3dDrvNotifyDestroyScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
257{
258 VBOX3DNOTIFY n;
259 n.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_DESTROYED;
260 n.iDisplay = pScreen->idScreen;
261 n.u32Reserved = 0;
262 n.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
263 RT_ZERO(n.au8Data);
264
265 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n);
266}
267
268
269static int vmsvga3dDrvNotifyBindSurface(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, HANDLE hSharedSurface)
270{
271 VBOX3DNOTIFY n;
272 n.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_BIND_SURFACE;
273 n.iDisplay = pScreen->idScreen;
274 n.u32Reserved = 0;
275 n.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
276 *(uint64_t *)&n.au8Data[0] = (uint64_t)hSharedSurface;
277
278 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n);
279}
280
281
282static int vmsvga3dDrvNotifyUpdate(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen,
283 uint32_t x, uint32_t y, uint32_t w, uint32_t h)
284{
285 typedef struct VBOX3DNOTIFYUPDATE
286 {
287 VBOX3DNOTIFY Core;
288 uint32_t x;
289 uint32_t y;
290 uint32_t w;
291 uint32_t h;
292 } VBOX3DNOTIFYUPDATE;
293
294 VBOX3DNOTIFYUPDATE n;
295 n.Core.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_UPDATE_END;
296 n.Core.iDisplay = pScreen->idScreen;
297 n.Core.u32Reserved = 0;
298 n.Core.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
299 RT_ZERO(n.Core.au8Data);
300 n.x = x;
301 n.y = y;
302 n.w = w;
303 n.h = h;
304
305 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n.Core);
306}
307
308static int vmsvga3dHwScreenCreate(PVMSVGA3DSTATE pState, uint32_t cWidth, uint32_t cHeight, VMSVGAHWSCREEN *p)
309{
310 PVMSVGA3DBACKEND pBackend = pState->pBackend;
311
312 D3D11_TEXTURE2D_DESC td;
313 RT_ZERO(td);
314 td.Width = cWidth;
315 td.Height = cHeight;
316 td.MipLevels = 1;
317 td.ArraySize = 1;
318 td.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
319 td.SampleDesc.Count = 1;
320 td.SampleDesc.Quality = 0;
321 td.Usage = D3D11_USAGE_DEFAULT;
322 td.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
323 td.CPUAccessFlags = 0;
324 td.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
325
326 HRESULT hr = pBackend->pDevice->CreateTexture2D(&td, 0, &p->pTexture);
327 if (SUCCEEDED(hr))
328 {
329 /* Get the shared handle. */
330 hr = p->pTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&p->pDxgiResource);
331 if (SUCCEEDED(hr))
332 {
333 hr = p->pDxgiResource->GetSharedHandle(&p->SharedHandle);
334 if (SUCCEEDED(hr))
335 hr = p->pTexture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)&p->pDXGIKeyedMutex);
336 }
337 }
338
339 if (SUCCEEDED(hr))
340 return VINF_SUCCESS;
341
342 AssertFailed();
343 return VERR_NOT_SUPPORTED;
344}
345
346
347static void vmsvga3dHwScreenDestroy(PVMSVGA3DSTATE pState, VMSVGAHWSCREEN *p)
348{
349 RT_NOREF(pState);
350 D3D_RELEASE(p->pDXGIKeyedMutex);
351 D3D_RELEASE(p->pDxgiResource);
352 D3D_RELEASE(p->pTexture);
353 p->SharedHandle = 0;
354 p->sidScreenTarget = SVGA_ID_INVALID;
355}
356
357
358int vmsvga3dBackDefineScreen(PVGASTATE pThis, PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
359{
360 RT_NOREF(pThis, pThisCC, pScreen);
361
362 LogRel4(("VMSVGA: vmsvga3dBackDefineScreen: screen %u\n", pScreen->idScreen));
363
364 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
365 AssertReturn(pState, VERR_INVALID_STATE);
366
367 PVMSVGA3DBACKEND pBackend = pState->pBackend;
368 AssertReturn(pBackend, VERR_INVALID_STATE);
369
370 Assert(pScreen->pHwScreen == NULL);
371
372 VMSVGAHWSCREEN *p = (VMSVGAHWSCREEN *)RTMemAllocZ(sizeof(VMSVGAHWSCREEN));
373 AssertPtrReturn(p, VERR_NO_MEMORY);
374
375 p->sidScreenTarget = SVGA_ID_INVALID;
376
377 int rc = vmsvga3dDrvNotifyDefineScreen(pThisCC, pScreen);
378 if (RT_SUCCESS(rc))
379 {
380 /* The frontend supports the screen. Create the actual resource. */
381 rc = vmsvga3dHwScreenCreate(pState, pScreen->cWidth, pScreen->cHeight, p);
382 if (RT_SUCCESS(rc))
383 LogRel4(("VMSVGA: vmsvga3dBackDefineScreen: created\n"));
384 }
385
386 if (RT_SUCCESS(rc))
387 {
388 LogRel(("VMSVGA: Using HW accelerated screen %u\n", pScreen->idScreen));
389 pScreen->pHwScreen = p;
390 }
391 else
392 {
393 LogRel4(("VMSVGA: vmsvga3dBackDefineScreen: %Rrc\n", rc));
394 vmsvga3dHwScreenDestroy(pState, p);
395 RTMemFree(p);
396 }
397
398 return rc;
399}
400
401
402int vmsvga3dBackDestroyScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
403{
404 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
405 AssertReturn(pState, VERR_INVALID_STATE);
406
407 vmsvga3dDrvNotifyDestroyScreen(pThisCC, pScreen);
408
409 if (pScreen->pHwScreen)
410 {
411 vmsvga3dHwScreenDestroy(pState, pScreen->pHwScreen);
412 RTMemFree(pScreen->pHwScreen);
413 pScreen->pHwScreen = NULL;
414 }
415
416 return VINF_SUCCESS;
417}
418
419
420int vmsvga3dBackSurfaceBlitToScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen,
421 SVGASignedRect destRect, SVGA3dSurfaceImageId srcImage,
422 SVGASignedRect srcRect, uint32_t cRects, SVGASignedRect *paRects)
423{
424 RT_NOREF(pThisCC, pScreen, destRect, srcImage, srcRect, cRects, paRects);
425
426 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
427 AssertReturn(pState, VERR_INVALID_STATE);
428
429 PVMSVGA3DBACKEND pBackend = pState->pBackend;
430 AssertReturn(pBackend, VERR_INVALID_STATE);
431
432 VMSVGAHWSCREEN *p = pScreen->pHwScreen;
433 AssertReturn(p, VERR_NOT_SUPPORTED);
434
435 PVMSVGA3DSURFACE pSurface;
436 int rc = vmsvga3dSurfaceFromSid(pState, srcImage.sid, &pSurface);
437 AssertRCReturn(rc, rc);
438
439 /** @todo Implement. */
440 AssertFailed();
441 return VERR_NOT_IMPLEMENTED;
442}
443
444
445int vmsvga3dSurfaceMap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, SVGA3dBox const *pBox,
446 VMSVGA3D_SURFACE_MAP enmMapType, VMSVGA3D_MAPPED_SURFACE *pMap)
447{
448 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
449 AssertReturn(pState, VERR_INVALID_STATE);
450
451 PVMSVGA3DBACKEND pBackend = pState->pBackend;
452 AssertReturn(pBackend, VERR_INVALID_STATE);
453 AssertReturn(pBackend->pImmediateContext, VERR_INVALID_STATE);
454
455 PVMSVGA3DSURFACE pSurface;
456 int rc = vmsvga3dSurfaceFromSid(pState, pImage->sid, &pSurface);
457 AssertRCReturn(rc, rc);
458
459 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
460 if (!pBackendSurface)
461 return VERR_INVALID_PARAMETER;
462
463 SVGA3dBox clipBox;
464 if (pBox)
465 {
466 clipBox = *pBox;
467 vmsvgaR3ClipBox(&pSurface->paMipmapLevels[0].mipmapSize, &clipBox);
468 ASSERT_GUEST_RETURN(clipBox.w && clipBox.h && clipBox.d, VERR_INVALID_PARAMETER);
469 }
470 else
471 {
472 clipBox.x = 0;
473 clipBox.y = 0;
474 clipBox.z = 0;
475 clipBox.w = pSurface->paMipmapLevels[0].mipmapSize.width;
476 clipBox.h = pSurface->paMipmapLevels[0].mipmapSize.height;
477 clipBox.d = pSurface->paMipmapLevels[0].mipmapSize.depth;
478 }
479
480 /** @todo D3D11_MAP_WRITE does not work with D3D11_USAGE_DYNAMIC resources. Probably VMSVGA3D_SURFACE_MAP_WRITE is not necessary. */
481 D3D11_MAP d3d11MapType;
482 switch (enmMapType)
483 {
484 case VMSVGA3D_SURFACE_MAP_READ: d3d11MapType = D3D11_MAP_READ; break;
485 case VMSVGA3D_SURFACE_MAP_WRITE: d3d11MapType = D3D11_MAP_WRITE; break;
486 case VMSVGA3D_SURFACE_MAP_READ_WRITE: d3d11MapType = D3D11_MAP_READ_WRITE; break;
487 case VMSVGA3D_SURFACE_MAP_WRITE_DISCARD: d3d11MapType = D3D11_MAP_WRITE_DISCARD; break;
488 default:
489 AssertFailed();
490 return VERR_INVALID_PARAMETER;
491 }
492
493 D3D11_MAPPED_SUBRESOURCE mappedResource;
494 RT_ZERO(mappedResource);
495
496 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
497 {
498 ID3D11Texture2D *pMappedTexture;
499 if (enmMapType == VMSVGA3D_SURFACE_MAP_READ)
500 {
501 pMappedTexture = pBackendSurface->u.ScreenTarget.pStagingTexture;
502
503 /* Copy the texture content to the staging texture. */
504 pBackend->pImmediateContext->CopyResource(pBackendSurface->u.ScreenTarget.pStagingTexture, pBackendSurface->u.ScreenTarget.pTexture);
505 }
506 else
507 pMappedTexture = pBackendSurface->u.ScreenTarget.pDynamicTexture;
508
509 UINT const Subresource = 0; /* Screen target surfaces have only one subresource. */
510 HRESULT hr = pBackend->pImmediateContext->Map(pMappedTexture, Subresource,
511 d3d11MapType, /* MapFlags = */ 0, &mappedResource);
512 if (SUCCEEDED(hr))
513 {
514 pMap->enmMapType = enmMapType;
515 pMap->box = clipBox;
516 pMap->cbPixel = pSurface->cbBlock;
517 pMap->cbRowPitch = mappedResource.RowPitch;
518 pMap->cbDepthPitch = mappedResource.DepthPitch;
519 pMap->pvData = (uint8_t *)mappedResource.pData
520 + pMap->box.x * pMap->cbPixel
521 + pMap->box.y * pMap->cbRowPitch
522 + pMap->box.z * pMap->cbDepthPitch;
523 }
524 else
525 rc = VERR_NOT_SUPPORTED;
526 }
527 else
528 {
529 // UINT D3D11CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT MipLevels);
530 /** @todo Implement. */
531 AssertFailed();
532 rc = VERR_NOT_IMPLEMENTED;
533 }
534
535 return rc;
536}
537
538
539int vmsvga3dSurfaceUnmap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, VMSVGA3D_MAPPED_SURFACE *pMap, bool fWritten)
540{
541 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
542 AssertReturn(pState, VERR_INVALID_STATE);
543
544 PVMSVGA3DBACKEND pBackend = pState->pBackend;
545 AssertReturn(pBackend, VERR_INVALID_STATE);
546 AssertReturn(pBackend->pImmediateContext, VERR_INVALID_STATE);
547
548 PVMSVGA3DSURFACE pSurface;
549 int rc = vmsvga3dSurfaceFromSid(pState, pImage->sid, &pSurface);
550 AssertRCReturn(rc, rc);
551
552 /* The called should not use the function for system memory surfaces. */
553 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
554 AssertReturn(pBackendSurface, VERR_INVALID_PARAMETER);
555
556 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
557 {
558 ID3D11Texture2D *pMappedTexture;
559 if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ)
560 pMappedTexture = pBackendSurface->u.ScreenTarget.pStagingTexture;
561 else
562 pMappedTexture = pBackendSurface->u.ScreenTarget.pDynamicTexture;
563
564 UINT const Subresource = 0; /* Screen target surfaces have only one subresource. */
565 pBackend->pImmediateContext->Unmap(pMappedTexture, Subresource);
566
567 if ( fWritten
568 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
569 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
570 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
571 {
572 ID3D11Resource *pDstResource = pBackendSurface->u.ScreenTarget.pTexture;
573 UINT DstSubresource = Subresource;
574 UINT DstX = pMap->box.x;
575 UINT DstY = pMap->box.y;
576 UINT DstZ = pMap->box.z;
577 ID3D11Resource *pSrcResource = pBackendSurface->u.ScreenTarget.pDynamicTexture;
578 UINT SrcSubresource = Subresource;
579 D3D11_BOX SrcBox;
580 SrcBox.left = pMap->box.x;
581 SrcBox.top = pMap->box.y;
582 SrcBox.front = pMap->box.z;
583 SrcBox.right = pMap->box.x + pMap->box.w;
584 SrcBox.bottom = pMap->box.y + pMap->box.h;
585 SrcBox.back = pMap->box.z + pMap->box.d;
586 pBackend->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
587 pSrcResource, SrcSubresource, &SrcBox);
588 }
589 }
590 else
591 {
592 AssertFailed();
593 rc = VERR_NOT_IMPLEMENTED;
594 }
595
596 return rc;
597}
598
599
600int vmsvga3dBackSurfaceCreateScreenTarget(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface)
601{
602 PVMSVGA3DBACKEND pBackend = pState->pBackend;
603 AssertReturn(pBackend, VERR_INVALID_STATE);
604 AssertReturn(pBackend->pDevice, VERR_INVALID_STATE);
605
606 /* Surface must have SCREEN_TARGET flag. */
607 ASSERT_GUEST_RETURN(RT_BOOL(pSurface->surfaceFlags & SVGA3D_SURFACE_SCREENTARGET), VERR_INVALID_PARAMETER);
608
609 if (VMSVGA3DSURFACE_HAS_HW_SURFACE(pSurface))
610 {
611 AssertFailed(); /* Should the function not be used like that? */
612 vmsvga3dBackSurfaceDestroy(pState, pSurface);
613 }
614
615 PVMSVGA3DBACKENDSURFACE pBackendSurface = (PVMSVGA3DBACKENDSURFACE)RTMemAllocZ(sizeof(VMSVGA3DBACKENDSURFACE));
616 AssertPtrReturn(pBackendSurface, VERR_NO_MEMORY);
617
618 D3D11_TEXTURE2D_DESC td;
619 RT_ZERO(td);
620 td.Width = pSurface->paMipmapLevels[0].mipmapSize.width;
621 td.Height = pSurface->paMipmapLevels[0].mipmapSize.height;
622 Assert(pSurface->cLevels == 1);
623 td.MipLevels = 1;
624 td.ArraySize = 1;
625 td.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
626 td.SampleDesc.Count = 1;
627 td.SampleDesc.Quality = 0;
628 td.Usage = D3D11_USAGE_DEFAULT;
629 td.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
630 td.CPUAccessFlags = 0;
631 td.MiscFlags = 0;
632
633 HRESULT hr = pBackend->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->u.ScreenTarget.pTexture);
634
635 if (SUCCEEDED(hr))
636 {
637 /* Map-able texture. */
638 td.Usage = D3D11_USAGE_DYNAMIC;
639 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
640 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
641 td.MiscFlags = 0;
642 hr = pBackend->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->u.ScreenTarget.pDynamicTexture);
643 }
644
645 if (SUCCEEDED(hr))
646 {
647 /* Staging texture. */
648 td.Usage = D3D11_USAGE_STAGING;
649 td.BindFlags = 0; /* No flags allowed. */
650 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
651 td.MiscFlags = 0;
652 hr = pBackend->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->u.ScreenTarget.pStagingTexture);
653 }
654
655 if (SUCCEEDED(hr))
656 {
657 /*
658 * Success.
659 */
660 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_SCREEN_TARGET;
661 pSurface->pBackendSurface = pBackendSurface;
662 return VINF_SUCCESS;
663 }
664
665 /* Failure. */
666 D3D_RELEASE(pBackendSurface->u.ScreenTarget.pStagingTexture);
667 D3D_RELEASE(pBackendSurface->u.ScreenTarget.pDynamicTexture);
668 D3D_RELEASE(pBackendSurface->u.ScreenTarget.pTexture);
669 RTMemFree(pBackendSurface);
670 return VERR_NO_MEMORY;
671}
672
673
674int vmsvga3dScreenTargetBind(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, uint32_t sid)
675{
676 int rc = VINF_SUCCESS;
677
678 PVMSVGA3DSURFACE pSurface;
679 if (sid != SVGA_ID_INVALID)
680 {
681 /* Create the surface if does not yet exist. */
682 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
683 AssertReturn(pState, VERR_INVALID_STATE);
684
685 rc = vmsvga3dSurfaceFromSid(pState, sid, &pSurface);
686 AssertRCReturn(rc, rc);
687
688 if (!VMSVGA3DSURFACE_HAS_HW_SURFACE(pSurface))
689 {
690 /* Create the actual texture. */
691 rc = vmsvga3dBackSurfaceCreateScreenTarget(pState, pSurface);
692 AssertRCReturn(rc, rc);
693 }
694 }
695 else
696 pSurface = NULL;
697
698 /* Notify the HW accelerated screen if it is used. */
699 VMSVGAHWSCREEN *pHwScreen = pScreen->pHwScreen;
700 if (!pHwScreen)
701 return VINF_SUCCESS;
702
703 /* Same surface -> do nothing. */
704 if (pHwScreen->sidScreenTarget == sid)
705 return VINF_SUCCESS;
706
707 if (sid != SVGA_ID_INVALID)
708 {
709 AssertReturn( pSurface->pBackendSurface
710 && pSurface->pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET, VERR_INVALID_PARAMETER);
711
712 HANDLE const hSharedSurface = pHwScreen->SharedHandle;
713 rc = vmsvga3dDrvNotifyBindSurface(pThisCC, pScreen, hSharedSurface);
714 }
715
716 if (RT_SUCCESS(rc))
717 {
718 pHwScreen->sidScreenTarget = sid;
719 }
720
721 return rc;
722}
723
724
725int vmsvga3dScreenTargetUpdate(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, SVGA3dRect const *pRect)
726{
727 VMSVGAHWSCREEN *pHwScreen = pScreen->pHwScreen;
728 AssertReturn(pHwScreen, VERR_NOT_SUPPORTED);
729
730 if (pHwScreen->sidScreenTarget == SVGA_ID_INVALID)
731 return VINF_SUCCESS; /* No surface bound. */
732
733 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
734 AssertReturn(pState, VERR_INVALID_STATE);
735
736 PVMSVGA3DBACKEND pBackend = pState->pBackend;
737 AssertReturn(pBackend, VERR_INVALID_STATE);
738
739 PVMSVGA3DSURFACE pSurface;
740 int rc = vmsvga3dSurfaceFromSid(pState, pHwScreen->sidScreenTarget, &pSurface);
741 AssertRCReturn(rc, rc);
742
743 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
744 AssertReturn(pBackendSurface, VERR_INVALID_PARAMETER);
745
746 SVGA3dRect boundRect;
747 boundRect.x = 0;
748 boundRect.y = 0;
749 boundRect.w = pSurface->paMipmapLevels[0].mipmapSize.width;
750 boundRect.h = pSurface->paMipmapLevels[0].mipmapSize.height;
751 SVGA3dRect clipRect = *pRect;
752 vmsvgaR3Clip3dRect(&boundRect, &clipRect);
753 ASSERT_GUEST_RETURN(clipRect.w && clipRect.h, VERR_INVALID_PARAMETER);
754
755 /* Copy the screen texture to the shared surface. */
756 DWORD result = pHwScreen->pDXGIKeyedMutex->AcquireSync(0, 10000);
757 if (result == WAIT_OBJECT_0)
758 {
759 ID3D11Query *pQuery = 0;
760 D3D11_QUERY_DESC qd;
761 RT_ZERO(qd);
762 qd.Query = D3D11_QUERY_EVENT;
763 HRESULT hr2 = pBackend->pDevice->CreateQuery(&qd, &pQuery);
764 Assert(hr2 == S_OK); RT_NOREF(hr2);
765
766 pBackend->pImmediateContext->CopyResource(pHwScreen->pTexture, pBackendSurface->u.ScreenTarget.pTexture);
767
768 pBackend->pImmediateContext->Flush();
769
770 pBackend->pImmediateContext->End(pQuery);
771
772 BOOL queryData;
773 while (pBackend->pImmediateContext->GetData(pQuery, &queryData, sizeof(queryData), 0) != S_OK)
774 {
775 RTThreadYield();
776 }
777 D3D_RELEASE(pQuery);
778
779 result = pHwScreen->pDXGIKeyedMutex->ReleaseSync(1);
780 }
781 else
782 AssertFailed();
783
784 rc = vmsvga3dDrvNotifyUpdate(pThisCC, pScreen, pRect->x, pRect->y, pRect->w, pRect->h);
785 return rc;
786}
787
788
789void vmsvga3dUpdateHostScreenViewport(PVGASTATECC pThisCC, uint32_t idScreen, VMSVGAVIEWPORT const *pOldViewport)
790{
791 RT_NOREF(pThisCC, idScreen, pOldViewport);
792 /** @todo Scroll the screen content without requiring the guest to redraw. */
793}
794
795
796int vmsvga3dQueryCaps(PVGASTATECC pThisCC, uint32_t idx3dCaps, uint32_t *pu32Val)
797{
798 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
799 AssertReturn(pState, VERR_INVALID_STATE);
800
801 int rc = VINF_SUCCESS;
802
803 switch (idx3dCaps)
804 {
805 case SVGA3D_DEVCAP_3D:
806 *pu32Val = 1;
807 break;
808
809 case SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH:
810 *pu32Val = 8192;
811 break;
812
813 case SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT:
814 *pu32Val = 8192;
815 break;
816
817 case SVGA3D_DEVCAP_DX:
818 *pu32Val = 1;
819 break;
820
821 default:
822 *pu32Val = 0;
823 rc = VERR_NOT_SUPPORTED;
824 }
825
826 return rc;
827}
828
829
830/* Handle resize */
831int vmsvga3dChangeMode(PVGASTATECC pThisCC)
832{
833 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
834 AssertReturn(pState, VERR_INVALID_STATE);
835
836 return VINF_SUCCESS;
837}
838
839
840int vmsvga3dSurfaceCopy(PVGASTATECC pThisCC, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src,
841 uint32_t cCopyBoxes, SVGA3dCopyBox *pBox)
842{
843 RT_NOREF(dest, src, cCopyBoxes, pBox);
844
845 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
846 AssertReturn(pState, VERR_INVALID_STATE);
847
848 AssertFailed();
849 return VERR_NOT_IMPLEMENTED;
850}
851
852
853/**
854 * Create a new 3d context
855 *
856 * @returns VBox status code.
857 * @param pThisCC The VGA/VMSVGA state for ring-3.
858 * @param cid Context id
859 */
860int vmsvga3dContextDefine(PVGASTATECC pThisCC, uint32_t cid)
861{
862 RT_NOREF(cid);
863
864 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
865 AssertReturn(pState, VERR_INVALID_STATE);
866
867 AssertFailed();
868 return VERR_NOT_IMPLEMENTED;
869}
870
871
872/**
873 * Destroy an existing 3d context
874 *
875 * @returns VBox status code.
876 * @param pThisCC The VGA/VMSVGA state for ring-3.
877 * @param cid Context id
878 */
879int vmsvga3dContextDestroy(PVGASTATECC pThisCC, uint32_t cid)
880{
881 RT_NOREF(cid);
882
883 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
884 AssertReturn(pState, VERR_INVALID_STATE);
885
886 AssertFailed();
887 return VINF_SUCCESS;
888}
889
890
891int vmsvga3dSetTransform(PVGASTATECC pThisCC, uint32_t cid, SVGA3dTransformType type, float matrix[16])
892{
893 RT_NOREF(cid, type, matrix);
894
895 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
896 AssertReturn(pState, VERR_INVALID_STATE);
897
898 AssertFailed();
899 return VINF_SUCCESS;
900}
901
902
903int vmsvga3dSetZRange(PVGASTATECC pThisCC, uint32_t cid, SVGA3dZRange zRange)
904{
905 RT_NOREF(cid, zRange);
906
907 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
908 AssertReturn(pState, VERR_INVALID_STATE);
909
910 AssertFailed();
911 return VINF_SUCCESS;
912}
913
914
915int vmsvga3dSetRenderState(PVGASTATECC pThisCC, uint32_t cid, uint32_t cRenderStates, SVGA3dRenderState *pRenderState)
916{
917 RT_NOREF(cid, cRenderStates, pRenderState);
918
919 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
920 AssertReturn(pState, VERR_INVALID_STATE);
921
922 AssertFailed();
923 return VINF_SUCCESS;
924}
925
926
927int vmsvga3dSetRenderTarget(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRenderTargetType type, SVGA3dSurfaceImageId target)
928{
929 RT_NOREF(cid, type, target);
930
931 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
932 AssertReturn(pState, VERR_INVALID_STATE);
933
934 AssertFailed();
935 return VINF_SUCCESS;
936}
937
938
939int vmsvga3dSetTextureState(PVGASTATECC pThisCC, uint32_t cid, uint32_t cTextureStates, SVGA3dTextureState *pTextureState)
940{
941 RT_NOREF(cid, cTextureStates, pTextureState);
942
943 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
944 AssertReturn(pState, VERR_INVALID_STATE);
945
946 AssertFailed();
947 return VINF_SUCCESS;
948}
949
950
951int vmsvga3dSetMaterial(PVGASTATECC pThisCC, uint32_t cid, SVGA3dFace face, SVGA3dMaterial *pMaterial)
952{
953 RT_NOREF(cid, face, pMaterial);
954
955 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
956 AssertReturn(pState, VERR_INVALID_STATE);
957
958 AssertFailed();
959 return VINF_SUCCESS;
960}
961
962
963int vmsvga3dSetLightData(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, SVGA3dLightData *pData)
964{
965 RT_NOREF(cid, index, pData);
966
967 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
968 AssertReturn(pState, VERR_INVALID_STATE);
969
970 AssertFailed();
971 return VINF_SUCCESS;
972}
973
974
975int vmsvga3dSetLightEnabled(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, uint32_t enabled)
976{
977 RT_NOREF(cid, index, enabled);
978
979 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
980 AssertReturn(pState, VERR_INVALID_STATE);
981
982 AssertFailed();
983 return VINF_SUCCESS;
984}
985
986
987int vmsvga3dSetViewPort(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRect *pRect)
988{
989 RT_NOREF(cid, pRect);
990
991 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
992 AssertReturn(pState, VERR_INVALID_STATE);
993
994 AssertFailed();
995 return VINF_SUCCESS;
996}
997
998
999int vmsvga3dSetClipPlane(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, float plane[4])
1000{
1001 RT_NOREF(cid, index, plane);
1002
1003 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1004 AssertReturn(pState, VERR_INVALID_STATE);
1005
1006 AssertFailed();
1007 return VINF_SUCCESS;
1008}
1009
1010
1011int vmsvga3dCommandClear(PVGASTATECC pThisCC, uint32_t cid, SVGA3dClearFlag clearFlag, uint32_t color, float depth,
1012 uint32_t stencil, uint32_t cRects, SVGA3dRect *pRect)
1013{
1014 /* From SVGA3D_BeginClear comments:
1015 *
1016 * Clear is not affected by clipping, depth test, or other
1017 * render state which affects the fragment pipeline.
1018 *
1019 * Therefore this code must ignore the current scissor rect.
1020 */
1021
1022 RT_NOREF(cid, clearFlag, color, depth, stencil, cRects, pRect);
1023
1024 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1025 AssertReturn(pState, VERR_INVALID_STATE);
1026
1027 AssertFailed();
1028 return VINF_SUCCESS;
1029}
1030
1031
1032int vmsvga3dDrawPrimitives(PVGASTATECC pThisCC, uint32_t cid, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl,
1033 uint32_t numRanges, SVGA3dPrimitiveRange *pRange,
1034 uint32_t cVertexDivisor, SVGA3dVertexDivisor *pVertexDivisor)
1035{
1036 RT_NOREF(cid, numVertexDecls, pVertexDecl, numRanges, pRange, cVertexDivisor, pVertexDivisor);
1037
1038 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1039 AssertReturn(pState, VERR_INVALID_STATE);
1040
1041 AssertFailed();
1042 return VINF_SUCCESS;
1043}
1044
1045
1046int vmsvga3dSetScissorRect(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRect *pRect)
1047{
1048 RT_NOREF(cid, pRect);
1049
1050 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1051 AssertReturn(pState, VERR_INVALID_STATE);
1052
1053 AssertFailed();
1054 return VINF_SUCCESS;
1055}
1056
1057
1058int vmsvga3dGenerateMipmaps(PVGASTATECC pThisCC, uint32_t sid, SVGA3dTextureFilter filter)
1059{
1060 RT_NOREF(sid, filter);
1061
1062 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1063 AssertReturn(pState, VERR_INVALID_STATE);
1064
1065 AssertFailed();
1066 return VINF_SUCCESS;
1067}
1068
1069
1070int vmsvga3dShaderDefine(PVGASTATECC pThisCC, uint32_t cid, uint32_t shid, SVGA3dShaderType type,
1071 uint32_t cbData, uint32_t *pShaderData)
1072{
1073 RT_NOREF(cid, shid, type, cbData, pShaderData);
1074
1075 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1076 AssertReturn(pState, VERR_INVALID_STATE);
1077
1078 AssertFailed();
1079 return VINF_SUCCESS;
1080}
1081
1082
1083int vmsvga3dShaderDestroy(PVGASTATECC pThisCC, uint32_t cid, uint32_t shid, SVGA3dShaderType type)
1084{
1085 RT_NOREF(cid, shid, type);
1086
1087 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1088 AssertReturn(pState, VERR_INVALID_STATE);
1089
1090 AssertFailed();
1091 return VINF_SUCCESS;
1092}
1093
1094
1095int vmsvga3dShaderSet(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext, uint32_t cid, SVGA3dShaderType type, uint32_t shid)
1096{
1097 RT_NOREF(pContext, cid, type, shid);
1098
1099 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1100 AssertReturn(pState, VERR_INVALID_STATE);
1101
1102 AssertFailed();
1103 return VINF_SUCCESS;
1104}
1105
1106
1107int vmsvga3dShaderSetConst(PVGASTATECC pThisCC, uint32_t cid, uint32_t reg, SVGA3dShaderType type,
1108 SVGA3dShaderConstType ctype, uint32_t cRegisters, uint32_t *pValues)
1109{
1110 RT_NOREF(cid, reg, type, ctype, cRegisters, pValues);
1111
1112 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1113 AssertReturn(pState, VERR_INVALID_STATE);
1114
1115 AssertFailed();
1116 return VINF_SUCCESS;
1117}
1118
1119
1120/**
1121 * Destroy backend specific surface bits (part of SVGA_3D_CMD_SURFACE_DESTROY).
1122 *
1123 * @param pState The VMSVGA3d state.
1124 * @param pSurface The surface being destroyed.
1125 */
1126void vmsvga3dBackSurfaceDestroy(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface)
1127{
1128 PVMSVGA3DBACKEND pBackend = pState->pBackend;
1129 AssertReturnVoid(pBackend);
1130 AssertReturnVoid(pBackend->pImmediateContext);
1131
1132 /* The caller should not use the function for system memory surfaces. */
1133 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
1134 AssertReturnVoid(pBackendSurface);
1135 pSurface->pBackendSurface = NULL;
1136
1137 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
1138 {
1139 D3D_RELEASE(pBackendSurface->u.ScreenTarget.pStagingTexture);
1140 D3D_RELEASE(pBackendSurface->u.ScreenTarget.pDynamicTexture);
1141 D3D_RELEASE(pBackendSurface->u.ScreenTarget.pTexture);
1142 }
1143 else
1144 {
1145 AssertFailed();
1146 }
1147
1148 RTMemFree(pBackendSurface);
1149}
1150
1151
1152/**
1153 * Backend worker for implementing SVGA_3D_CMD_SURFACE_STRETCHBLT.
1154 *
1155 * @returns VBox status code.
1156 * @param pThis The VGA device instance.
1157 * @param pState The VMSVGA3d state.
1158 * @param pDstSurface The destination host surface.
1159 * @param uDstFace The destination face (valid).
1160 * @param uDstMipmap The destination mipmap level (valid).
1161 * @param pDstBox The destination box.
1162 * @param pSrcSurface The source host surface.
1163 * @param uSrcFace The destination face (valid).
1164 * @param uSrcMipmap The source mimap level (valid).
1165 * @param pSrcBox The source box.
1166 * @param enmMode The strecht blt mode .
1167 * @param pContext The VMSVGA3d context (already current for OGL).
1168 */
1169int vmsvga3dBackSurfaceStretchBlt(PVGASTATE pThis, PVMSVGA3DSTATE pState,
1170 PVMSVGA3DSURFACE pDstSurface, uint32_t uDstFace, uint32_t uDstMipmap, SVGA3dBox const *pDstBox,
1171 PVMSVGA3DSURFACE pSrcSurface, uint32_t uSrcFace, uint32_t uSrcMipmap, SVGA3dBox const *pSrcBox,
1172 SVGA3dStretchBltMode enmMode, PVMSVGA3DCONTEXT pContext)
1173{
1174 RT_NOREF(pThis, pState, pDstSurface, uDstFace, uDstMipmap, pDstBox,
1175 pSrcSurface, uSrcFace, uSrcMipmap, pSrcBox, enmMode, pContext);
1176
1177 AssertFailed();
1178 return VINF_SUCCESS;
1179}
1180
1181
1182/**
1183 * Backend worker for implementing SVGA_3D_CMD_SURFACE_DMA that copies one box.
1184 *
1185 * @returns Failure status code or @a rc.
1186 * @param pThis The shared VGA/VMSVGA instance data.
1187 * @param pThisCC The VGA/VMSVGA state for ring-3.
1188 * @param pState The VMSVGA3d state.
1189 * @param pSurface The host surface.
1190 * @param pMipLevel Mipmap level. The caller knows it already.
1191 * @param uHostFace The host face (valid).
1192 * @param uHostMipmap The host mipmap level (valid).
1193 * @param GuestPtr The guest pointer.
1194 * @param cbGuestPitch The guest pitch.
1195 * @param transfer The transfer direction.
1196 * @param pBox The box to copy (clipped, valid, except for guest's srcx, srcy, srcz).
1197 * @param pContext The context (for OpenGL).
1198 * @param rc The current rc for all boxes.
1199 * @param iBox The current box number (for Direct 3D).
1200 */
1201int vmsvga3dBackSurfaceDMACopyBox(PVGASTATE pThis, PVGASTATECC pThisCC, PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface,
1202 PVMSVGA3DMIPMAPLEVEL pMipLevel, uint32_t uHostFace, uint32_t uHostMipmap,
1203 SVGAGuestPtr GuestPtr, uint32_t cbGuestPitch, SVGA3dTransferType transfer,
1204 SVGA3dCopyBox const *pBox, PVMSVGA3DCONTEXT pContext, int rc, int iBox)
1205{
1206 RT_NOREF(pState, pMipLevel, pContext, iBox);
1207
1208 /* The called should not use the function for system memory surfaces. */
1209 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
1210 AssertReturn(pBackendSurface, VERR_INVALID_PARAMETER);
1211
1212 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
1213 {
1214 /** @todo This is generic code and should be in DevVGA-SVGA3d.cpp for backends which support Map/Unmap. */
1215 AssertReturn(uHostFace == 0 && uHostMipmap == 0, VERR_INVALID_PARAMETER);
1216 AssertReturn(transfer == SVGA3D_WRITE_HOST_VRAM, VERR_NOT_IMPLEMENTED); /** @todo Implement */
1217
1218 uint32_t const u32GuestBlockX = pBox->srcx / pSurface->cxBlock;
1219 uint32_t const u32GuestBlockY = pBox->srcy / pSurface->cyBlock;
1220 Assert(u32GuestBlockX * pSurface->cxBlock == pBox->srcx);
1221 Assert(u32GuestBlockY * pSurface->cyBlock == pBox->srcy);
1222 uint32_t const cBlocksX = (pBox->w + pSurface->cxBlock - 1) / pSurface->cxBlock;
1223 uint32_t const cBlocksY = (pBox->h + pSurface->cyBlock - 1) / pSurface->cyBlock;
1224 AssertMsgReturn(cBlocksX && cBlocksY, ("Empty box %dx%d\n", pBox->w, pBox->h), VERR_INTERNAL_ERROR);
1225
1226 /* vmsvgaR3GmrTransfer verifies uGuestOffset.
1227 * srcx(u32GuestBlockX) and srcy(u32GuestBlockY) have been verified in vmsvga3dSurfaceDMA
1228 * to not cause 32 bit overflow when multiplied by cbBlock and cbGuestPitch.
1229 */
1230 uint64_t const uGuestOffset = u32GuestBlockX * pSurface->cbBlock + u32GuestBlockY * cbGuestPitch;
1231 AssertReturn(uGuestOffset < UINT32_MAX, VERR_INVALID_PARAMETER);
1232
1233 SVGA3dSurfaceImageId image;
1234 image.sid = pSurface->id;
1235 image.face = uHostFace;
1236 image.mipmap = uHostMipmap;
1237
1238 SVGA3dBox box;
1239 box.x = pBox->x;
1240 box.y = pBox->y;
1241 box.z = 0;
1242 box.w = pBox->w;
1243 box.h = pBox->h;
1244 box.d = 1;
1245
1246 VMSVGA3D_MAPPED_SURFACE map;
1247 rc = vmsvga3dSurfaceMap(pThisCC, &image, &box, VMSVGA3D_SURFACE_MAP_WRITE_DISCARD, &map);
1248 if (RT_SUCCESS(rc))
1249 {
1250 /* Prepare parameters for vmsvgaR3GmrTransfer, which needs the host buffer address, size
1251 * and offset of the first scanline.
1252 */
1253 uint32_t const cbLockedBuf = map.cbRowPitch * cBlocksY;
1254 uint8_t *pu8LockedBuf = (uint8_t *)map.pvData;
1255 uint32_t const offLockedBuf = 0;
1256
1257 rc = vmsvgaR3GmrTransfer(pThis,
1258 pThisCC,
1259 transfer,
1260 pu8LockedBuf,
1261 cbLockedBuf,
1262 offLockedBuf,
1263 map.cbRowPitch,
1264 GuestPtr,
1265 (uint32_t)uGuestOffset,
1266 cbGuestPitch,
1267 cBlocksX * pSurface->cbBlock,
1268 cBlocksY);
1269 AssertRC(rc);
1270
1271 // Log4(("first line:\n%.*Rhxd\n", cBlocksX * pSurface->cbBlock, LockedRect.pBits));
1272
1273 //vmsvga3dMapWriteBmpFile(&map, "Dynamic");
1274
1275 vmsvga3dSurfaceUnmap(pThisCC, &image, &map, /* fWritten = */ true);
1276 }
1277#if 0
1278//ASMBreakpoint();
1279 rc = vmsvga3dSurfaceMap(pThisCC, &image, NULL, VMSVGA3D_SURFACE_MAP_READ, &map);
1280 if (RT_SUCCESS(rc))
1281 {
1282 vmsvga3dMapWriteBmpFile(&map, "Staging");
1283
1284 vmsvga3dSurfaceUnmap(pThisCC, &image, &map, /* fWritten = */ false);
1285 }
1286#endif
1287 }
1288 else
1289 {
1290 AssertMsgFailed(("Unsupported surface type %d\n", pBackendSurface->enmResType));
1291 rc = VERR_NOT_IMPLEMENTED;
1292 }
1293
1294 return rc;
1295}
1296
1297
1298/**
1299 * Create D3D/OpenGL texture object for the specified surface.
1300 *
1301 * Surfaces are created when needed.
1302 *
1303 * @param pState The VMSVGA3d state.
1304 * @param pContext The context.
1305 * @param idAssociatedContext Probably the same as pContext->id.
1306 * @param pSurface The surface to create the texture for.
1307 */
1308int vmsvga3dBackCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext,
1309 PVMSVGA3DSURFACE pSurface)
1310
1311{
1312 RT_NOREF(pState, pContext, idAssociatedContext, pSurface);
1313
1314 AssertFailed();
1315 return VINF_SUCCESS;
1316}
1317
1318
1319int vmsvga3dOcclusionQueryCreate(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext)
1320{
1321 RT_NOREF(pState, pContext);
1322 AssertFailed();
1323 return VINF_SUCCESS;
1324}
1325
1326
1327int vmsvga3dOcclusionQueryBegin(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext)
1328{
1329 RT_NOREF(pState, pContext);
1330 AssertFailed();
1331 return VINF_SUCCESS;
1332}
1333
1334
1335int vmsvga3dOcclusionQueryEnd(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext)
1336{
1337 RT_NOREF(pState, pContext);
1338 AssertFailed();
1339 return VINF_SUCCESS;
1340}
1341
1342
1343int vmsvga3dOcclusionQueryGetData(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t *pu32Pixels)
1344{
1345 RT_NOREF(pState, pContext);
1346 *pu32Pixels = 0;
1347 AssertFailed();
1348 return VINF_SUCCESS;
1349}
1350
1351
1352int vmsvga3dOcclusionQueryDelete(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext)
1353{
1354 RT_NOREF(pState, pContext);
1355 AssertFailed();
1356 return VINF_SUCCESS;
1357}
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