VirtualBox

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

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

Devices/Graphics: Initial commit of DX11 backend. bugref:9830

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 43.1 KB
Line 
1/* $Id: DevVGA-SVGA3d-win-dx.cpp 86836 2020-11-09 22:53:11Z 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_MAX_TEXTURE_WIDTH:
806 *pu32Val = 8192;
807 break;
808
809 case SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT:
810 *pu32Val = 8192;
811 break;
812
813 default:
814 *pu32Val = 0;
815 rc = VERR_NOT_SUPPORTED;
816 }
817
818 return rc;
819}
820
821
822/* Handle resize */
823int vmsvga3dChangeMode(PVGASTATECC pThisCC)
824{
825 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
826 AssertReturn(pState, VERR_INVALID_STATE);
827
828 return VINF_SUCCESS;
829}
830
831
832int vmsvga3dSurfaceCopy(PVGASTATECC pThisCC, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src,
833 uint32_t cCopyBoxes, SVGA3dCopyBox *pBox)
834{
835 RT_NOREF(dest, src, cCopyBoxes, pBox);
836
837 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
838 AssertReturn(pState, VERR_INVALID_STATE);
839
840 AssertFailed();
841 return VERR_NOT_IMPLEMENTED;
842}
843
844
845/**
846 * Create a new 3d context
847 *
848 * @returns VBox status code.
849 * @param pThisCC The VGA/VMSVGA state for ring-3.
850 * @param cid Context id
851 */
852int vmsvga3dContextDefine(PVGASTATECC pThisCC, uint32_t cid)
853{
854 RT_NOREF(cid);
855
856 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
857 AssertReturn(pState, VERR_INVALID_STATE);
858
859 AssertFailed();
860 return VERR_NOT_IMPLEMENTED;
861}
862
863
864/**
865 * Destroy an existing 3d context
866 *
867 * @returns VBox status code.
868 * @param pThisCC The VGA/VMSVGA state for ring-3.
869 * @param cid Context id
870 */
871int vmsvga3dContextDestroy(PVGASTATECC pThisCC, uint32_t cid)
872{
873 RT_NOREF(cid);
874
875 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
876 AssertReturn(pState, VERR_INVALID_STATE);
877
878 AssertFailed();
879 return VINF_SUCCESS;
880}
881
882
883int vmsvga3dSetTransform(PVGASTATECC pThisCC, uint32_t cid, SVGA3dTransformType type, float matrix[16])
884{
885 RT_NOREF(cid, type, matrix);
886
887 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
888 AssertReturn(pState, VERR_INVALID_STATE);
889
890 AssertFailed();
891 return VINF_SUCCESS;
892}
893
894
895int vmsvga3dSetZRange(PVGASTATECC pThisCC, uint32_t cid, SVGA3dZRange zRange)
896{
897 RT_NOREF(cid, zRange);
898
899 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
900 AssertReturn(pState, VERR_INVALID_STATE);
901
902 AssertFailed();
903 return VINF_SUCCESS;
904}
905
906
907int vmsvga3dSetRenderState(PVGASTATECC pThisCC, uint32_t cid, uint32_t cRenderStates, SVGA3dRenderState *pRenderState)
908{
909 RT_NOREF(cid, cRenderStates, pRenderState);
910
911 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
912 AssertReturn(pState, VERR_INVALID_STATE);
913
914 AssertFailed();
915 return VINF_SUCCESS;
916}
917
918
919int vmsvga3dSetRenderTarget(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRenderTargetType type, SVGA3dSurfaceImageId target)
920{
921 RT_NOREF(cid, type, target);
922
923 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
924 AssertReturn(pState, VERR_INVALID_STATE);
925
926 AssertFailed();
927 return VINF_SUCCESS;
928}
929
930
931int vmsvga3dSetTextureState(PVGASTATECC pThisCC, uint32_t cid, uint32_t cTextureStates, SVGA3dTextureState *pTextureState)
932{
933 RT_NOREF(cid, cTextureStates, pTextureState);
934
935 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
936 AssertReturn(pState, VERR_INVALID_STATE);
937
938 AssertFailed();
939 return VINF_SUCCESS;
940}
941
942
943int vmsvga3dSetMaterial(PVGASTATECC pThisCC, uint32_t cid, SVGA3dFace face, SVGA3dMaterial *pMaterial)
944{
945 RT_NOREF(cid, face, pMaterial);
946
947 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
948 AssertReturn(pState, VERR_INVALID_STATE);
949
950 AssertFailed();
951 return VINF_SUCCESS;
952}
953
954
955int vmsvga3dSetLightData(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, SVGA3dLightData *pData)
956{
957 RT_NOREF(cid, index, pData);
958
959 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
960 AssertReturn(pState, VERR_INVALID_STATE);
961
962 AssertFailed();
963 return VINF_SUCCESS;
964}
965
966
967int vmsvga3dSetLightEnabled(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, uint32_t enabled)
968{
969 RT_NOREF(cid, index, enabled);
970
971 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
972 AssertReturn(pState, VERR_INVALID_STATE);
973
974 AssertFailed();
975 return VINF_SUCCESS;
976}
977
978
979int vmsvga3dSetViewPort(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRect *pRect)
980{
981 RT_NOREF(cid, pRect);
982
983 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
984 AssertReturn(pState, VERR_INVALID_STATE);
985
986 AssertFailed();
987 return VINF_SUCCESS;
988}
989
990
991int vmsvga3dSetClipPlane(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, float plane[4])
992{
993 RT_NOREF(cid, index, plane);
994
995 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
996 AssertReturn(pState, VERR_INVALID_STATE);
997
998 AssertFailed();
999 return VINF_SUCCESS;
1000}
1001
1002
1003int vmsvga3dCommandClear(PVGASTATECC pThisCC, uint32_t cid, SVGA3dClearFlag clearFlag, uint32_t color, float depth,
1004 uint32_t stencil, uint32_t cRects, SVGA3dRect *pRect)
1005{
1006 /* From SVGA3D_BeginClear comments:
1007 *
1008 * Clear is not affected by clipping, depth test, or other
1009 * render state which affects the fragment pipeline.
1010 *
1011 * Therefore this code must ignore the current scissor rect.
1012 */
1013
1014 RT_NOREF(cid, clearFlag, color, depth, stencil, cRects, pRect);
1015
1016 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1017 AssertReturn(pState, VERR_INVALID_STATE);
1018
1019 AssertFailed();
1020 return VINF_SUCCESS;
1021}
1022
1023
1024int vmsvga3dDrawPrimitives(PVGASTATECC pThisCC, uint32_t cid, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl,
1025 uint32_t numRanges, SVGA3dPrimitiveRange *pRange,
1026 uint32_t cVertexDivisor, SVGA3dVertexDivisor *pVertexDivisor)
1027{
1028 RT_NOREF(cid, numVertexDecls, pVertexDecl, numRanges, pRange, cVertexDivisor, pVertexDivisor);
1029
1030 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1031 AssertReturn(pState, VERR_INVALID_STATE);
1032
1033 AssertFailed();
1034 return VINF_SUCCESS;
1035}
1036
1037
1038int vmsvga3dSetScissorRect(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRect *pRect)
1039{
1040 RT_NOREF(cid, pRect);
1041
1042 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1043 AssertReturn(pState, VERR_INVALID_STATE);
1044
1045 AssertFailed();
1046 return VINF_SUCCESS;
1047}
1048
1049
1050int vmsvga3dGenerateMipmaps(PVGASTATECC pThisCC, uint32_t sid, SVGA3dTextureFilter filter)
1051{
1052 RT_NOREF(sid, filter);
1053
1054 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1055 AssertReturn(pState, VERR_INVALID_STATE);
1056
1057 AssertFailed();
1058 return VINF_SUCCESS;
1059}
1060
1061
1062int vmsvga3dShaderDefine(PVGASTATECC pThisCC, uint32_t cid, uint32_t shid, SVGA3dShaderType type,
1063 uint32_t cbData, uint32_t *pShaderData)
1064{
1065 RT_NOREF(cid, shid, type, cbData, pShaderData);
1066
1067 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1068 AssertReturn(pState, VERR_INVALID_STATE);
1069
1070 AssertFailed();
1071 return VINF_SUCCESS;
1072}
1073
1074
1075int vmsvga3dShaderDestroy(PVGASTATECC pThisCC, uint32_t cid, uint32_t shid, SVGA3dShaderType type)
1076{
1077 RT_NOREF(cid, shid, type);
1078
1079 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1080 AssertReturn(pState, VERR_INVALID_STATE);
1081
1082 AssertFailed();
1083 return VINF_SUCCESS;
1084}
1085
1086
1087int vmsvga3dShaderSet(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext, uint32_t cid, SVGA3dShaderType type, uint32_t shid)
1088{
1089 RT_NOREF(pContext, cid, type, shid);
1090
1091 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1092 AssertReturn(pState, VERR_INVALID_STATE);
1093
1094 AssertFailed();
1095 return VINF_SUCCESS;
1096}
1097
1098
1099int vmsvga3dShaderSetConst(PVGASTATECC pThisCC, uint32_t cid, uint32_t reg, SVGA3dShaderType type,
1100 SVGA3dShaderConstType ctype, uint32_t cRegisters, uint32_t *pValues)
1101{
1102 RT_NOREF(cid, reg, type, ctype, cRegisters, pValues);
1103
1104 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1105 AssertReturn(pState, VERR_INVALID_STATE);
1106
1107 AssertFailed();
1108 return VINF_SUCCESS;
1109}
1110
1111
1112/**
1113 * Destroy backend specific surface bits (part of SVGA_3D_CMD_SURFACE_DESTROY).
1114 *
1115 * @param pState The VMSVGA3d state.
1116 * @param pSurface The surface being destroyed.
1117 */
1118void vmsvga3dBackSurfaceDestroy(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface)
1119{
1120 PVMSVGA3DBACKEND pBackend = pState->pBackend;
1121 AssertReturnVoid(pBackend);
1122 AssertReturnVoid(pBackend->pImmediateContext);
1123
1124 /* The caller should not use the function for system memory surfaces. */
1125 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
1126 AssertReturnVoid(pBackendSurface);
1127 pSurface->pBackendSurface = NULL;
1128
1129 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
1130 {
1131 D3D_RELEASE(pBackendSurface->u.ScreenTarget.pStagingTexture);
1132 D3D_RELEASE(pBackendSurface->u.ScreenTarget.pDynamicTexture);
1133 D3D_RELEASE(pBackendSurface->u.ScreenTarget.pTexture);
1134 }
1135 else
1136 {
1137 AssertFailed();
1138 }
1139
1140 RTMemFree(pBackendSurface);
1141}
1142
1143
1144/**
1145 * Backend worker for implementing SVGA_3D_CMD_SURFACE_STRETCHBLT.
1146 *
1147 * @returns VBox status code.
1148 * @param pThis The VGA device instance.
1149 * @param pState The VMSVGA3d state.
1150 * @param pDstSurface The destination host surface.
1151 * @param uDstFace The destination face (valid).
1152 * @param uDstMipmap The destination mipmap level (valid).
1153 * @param pDstBox The destination box.
1154 * @param pSrcSurface The source host surface.
1155 * @param uSrcFace The destination face (valid).
1156 * @param uSrcMipmap The source mimap level (valid).
1157 * @param pSrcBox The source box.
1158 * @param enmMode The strecht blt mode .
1159 * @param pContext The VMSVGA3d context (already current for OGL).
1160 */
1161int vmsvga3dBackSurfaceStretchBlt(PVGASTATE pThis, PVMSVGA3DSTATE pState,
1162 PVMSVGA3DSURFACE pDstSurface, uint32_t uDstFace, uint32_t uDstMipmap, SVGA3dBox const *pDstBox,
1163 PVMSVGA3DSURFACE pSrcSurface, uint32_t uSrcFace, uint32_t uSrcMipmap, SVGA3dBox const *pSrcBox,
1164 SVGA3dStretchBltMode enmMode, PVMSVGA3DCONTEXT pContext)
1165{
1166 RT_NOREF(pThis, pState, pDstSurface, uDstFace, uDstMipmap, pDstBox,
1167 pSrcSurface, uSrcFace, uSrcMipmap, pSrcBox, enmMode, pContext);
1168
1169 AssertFailed();
1170 return VINF_SUCCESS;
1171}
1172
1173
1174/**
1175 * Backend worker for implementing SVGA_3D_CMD_SURFACE_DMA that copies one box.
1176 *
1177 * @returns Failure status code or @a rc.
1178 * @param pThis The shared VGA/VMSVGA instance data.
1179 * @param pThisCC The VGA/VMSVGA state for ring-3.
1180 * @param pState The VMSVGA3d state.
1181 * @param pSurface The host surface.
1182 * @param pMipLevel Mipmap level. The caller knows it already.
1183 * @param uHostFace The host face (valid).
1184 * @param uHostMipmap The host mipmap level (valid).
1185 * @param GuestPtr The guest pointer.
1186 * @param cbGuestPitch The guest pitch.
1187 * @param transfer The transfer direction.
1188 * @param pBox The box to copy (clipped, valid, except for guest's srcx, srcy, srcz).
1189 * @param pContext The context (for OpenGL).
1190 * @param rc The current rc for all boxes.
1191 * @param iBox The current box number (for Direct 3D).
1192 */
1193int vmsvga3dBackSurfaceDMACopyBox(PVGASTATE pThis, PVGASTATECC pThisCC, PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface,
1194 PVMSVGA3DMIPMAPLEVEL pMipLevel, uint32_t uHostFace, uint32_t uHostMipmap,
1195 SVGAGuestPtr GuestPtr, uint32_t cbGuestPitch, SVGA3dTransferType transfer,
1196 SVGA3dCopyBox const *pBox, PVMSVGA3DCONTEXT pContext, int rc, int iBox)
1197{
1198 RT_NOREF(pState, pMipLevel, pContext, iBox);
1199
1200 /* The called should not use the function for system memory surfaces. */
1201 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
1202 AssertReturn(pBackendSurface, VERR_INVALID_PARAMETER);
1203
1204 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
1205 {
1206 /** @todo This is generic code and should be in DevVGA-SVGA3d.cpp for backends which support Map/Unmap. */
1207 AssertReturn(uHostFace == 0 && uHostMipmap == 0, VERR_INVALID_PARAMETER);
1208 AssertReturn(transfer == SVGA3D_WRITE_HOST_VRAM, VERR_NOT_IMPLEMENTED); /** @todo Implement */
1209
1210 uint32_t const u32GuestBlockX = pBox->srcx / pSurface->cxBlock;
1211 uint32_t const u32GuestBlockY = pBox->srcy / pSurface->cyBlock;
1212 Assert(u32GuestBlockX * pSurface->cxBlock == pBox->srcx);
1213 Assert(u32GuestBlockY * pSurface->cyBlock == pBox->srcy);
1214 uint32_t const cBlocksX = (pBox->w + pSurface->cxBlock - 1) / pSurface->cxBlock;
1215 uint32_t const cBlocksY = (pBox->h + pSurface->cyBlock - 1) / pSurface->cyBlock;
1216 AssertMsgReturn(cBlocksX && cBlocksY, ("Empty box %dx%d\n", pBox->w, pBox->h), VERR_INTERNAL_ERROR);
1217
1218 /* vmsvgaR3GmrTransfer verifies uGuestOffset.
1219 * srcx(u32GuestBlockX) and srcy(u32GuestBlockY) have been verified in vmsvga3dSurfaceDMA
1220 * to not cause 32 bit overflow when multiplied by cbBlock and cbGuestPitch.
1221 */
1222 uint64_t const uGuestOffset = u32GuestBlockX * pSurface->cbBlock + u32GuestBlockY * cbGuestPitch;
1223 AssertReturn(uGuestOffset < UINT32_MAX, VERR_INVALID_PARAMETER);
1224
1225 SVGA3dSurfaceImageId image;
1226 image.sid = pSurface->id;
1227 image.face = uHostFace;
1228 image.mipmap = uHostMipmap;
1229
1230 SVGA3dBox box;
1231 box.x = pBox->x;
1232 box.y = pBox->y;
1233 box.z = 0;
1234 box.w = pBox->w;
1235 box.h = pBox->h;
1236 box.d = 1;
1237
1238 VMSVGA3D_MAPPED_SURFACE map;
1239 rc = vmsvga3dSurfaceMap(pThisCC, &image, &box, VMSVGA3D_SURFACE_MAP_WRITE_DISCARD, &map);
1240 if (RT_SUCCESS(rc))
1241 {
1242 /* Prepare parameters for vmsvgaR3GmrTransfer, which needs the host buffer address, size
1243 * and offset of the first scanline.
1244 */
1245 uint32_t const cbLockedBuf = map.cbRowPitch * cBlocksY;
1246 uint8_t *pu8LockedBuf = (uint8_t *)map.pvData;
1247 uint32_t const offLockedBuf = 0;
1248
1249 rc = vmsvgaR3GmrTransfer(pThis,
1250 pThisCC,
1251 transfer,
1252 pu8LockedBuf,
1253 cbLockedBuf,
1254 offLockedBuf,
1255 map.cbRowPitch,
1256 GuestPtr,
1257 (uint32_t)uGuestOffset,
1258 cbGuestPitch,
1259 cBlocksX * pSurface->cbBlock,
1260 cBlocksY);
1261 AssertRC(rc);
1262
1263 // Log4(("first line:\n%.*Rhxd\n", cBlocksX * pSurface->cbBlock, LockedRect.pBits));
1264
1265 //vmsvga3dMapWriteBmpFile(&map, "Dynamic");
1266
1267 vmsvga3dSurfaceUnmap(pThisCC, &image, &map, /* fWritten = */ true);
1268 }
1269#if 0
1270//ASMBreakpoint();
1271 rc = vmsvga3dSurfaceMap(pThisCC, &image, NULL, VMSVGA3D_SURFACE_MAP_READ, &map);
1272 if (RT_SUCCESS(rc))
1273 {
1274 vmsvga3dMapWriteBmpFile(&map, "Staging");
1275
1276 vmsvga3dSurfaceUnmap(pThisCC, &image, &map, /* fWritten = */ false);
1277 }
1278#endif
1279 }
1280 else
1281 {
1282 AssertMsgFailed(("Unsupported surface type %d\n", pBackendSurface->enmResType));
1283 rc = VERR_NOT_IMPLEMENTED;
1284 }
1285
1286 return rc;
1287}
1288
1289
1290/**
1291 * Create D3D/OpenGL texture object for the specified surface.
1292 *
1293 * Surfaces are created when needed.
1294 *
1295 * @param pState The VMSVGA3d state.
1296 * @param pContext The context.
1297 * @param idAssociatedContext Probably the same as pContext->id.
1298 * @param pSurface The surface to create the texture for.
1299 */
1300int vmsvga3dBackCreateTexture(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext,
1301 PVMSVGA3DSURFACE pSurface)
1302
1303{
1304 RT_NOREF(pState, pContext, idAssociatedContext, pSurface);
1305
1306 AssertFailed();
1307 return VINF_SUCCESS;
1308}
1309
1310
1311int vmsvga3dOcclusionQueryCreate(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext)
1312{
1313 RT_NOREF(pState, pContext);
1314 AssertFailed();
1315 return VINF_SUCCESS;
1316}
1317
1318
1319int vmsvga3dOcclusionQueryBegin(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext)
1320{
1321 RT_NOREF(pState, pContext);
1322 AssertFailed();
1323 return VINF_SUCCESS;
1324}
1325
1326
1327int vmsvga3dOcclusionQueryEnd(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext)
1328{
1329 RT_NOREF(pState, pContext);
1330 AssertFailed();
1331 return VINF_SUCCESS;
1332}
1333
1334
1335int vmsvga3dOcclusionQueryGetData(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext, uint32_t *pu32Pixels)
1336{
1337 RT_NOREF(pState, pContext);
1338 *pu32Pixels = 0;
1339 AssertFailed();
1340 return VINF_SUCCESS;
1341}
1342
1343
1344int vmsvga3dOcclusionQueryDelete(PVMSVGA3DSTATE pState, PVMSVGA3DCONTEXT pContext)
1345{
1346 RT_NOREF(pState, pContext);
1347 AssertFailed();
1348 return VINF_SUCCESS;
1349}
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