VirtualBox

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

Last change on this file since 103914 was 103574, checked in by vboxsync, 8 months ago

Devices/Graphics,WDDM: translate ClearDepthStencilView flags

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 519.9 KB
Line 
1/* $Id: DevVGA-SVGA3d-dx-dx11.cpp 103574 2024-02-26 16:05:40Z vboxsync $ */
2/** @file
3 * DevVMWare - VMWare SVGA device
4 */
5
6/*
7 * Copyright (C) 2020-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32#define LOG_GROUP LOG_GROUP_DEV_VMSVGA
33#include <VBox/AssertGuest.h>
34#include <VBox/log.h>
35#include <VBox/vmm/pdmdev.h>
36#include <VBox/vmm/pgm.h>
37
38#include <iprt/asm-mem.h>
39#include <iprt/assert.h>
40#include <iprt/avl.h>
41#include <iprt/errcore.h>
42#include <iprt/mem.h>
43
44#include <VBoxVideo.h> /* required by DevVGA.h */
45#include <VBoxVideo3D.h>
46
47/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
48#include "DevVGA.h"
49
50#include "DevVGA-SVGA.h"
51#include "DevVGA-SVGA3d.h"
52#include "DevVGA-SVGA3d-internal.h"
53#include "DevVGA-SVGA3d-dx-shader.h"
54
55/* d3d11_1.h has a structure field named 'Status' but Status is defined as int on Linux host */
56#if defined(Status)
57#undef Status
58#endif
59#include <d3d11_1.h>
60
61
62#ifdef RT_OS_WINDOWS
63# define VBOX_D3D11_LIBRARY_NAME "d3d11"
64#else
65# define VBOX_D3D11_LIBRARY_NAME "VBoxDxVk"
66#endif
67
68/* One ID3D11Device object is used for all VMSVGA contexts. */
69/** @todo This should be the only option because VGPU freely uses surfaces from different VMSVGA contexts
70 * and synchronization of access to shared surfaces kills performance.
71 */
72#define DX_FORCE_SINGLE_DEVICE
73/* A single staging ID3D11Buffer is used for uploading data to other buffers. */
74#define DX_COMMON_STAGING_BUFFER
75/* Always flush after submitting a draw call for debugging. */
76//#define DX_FLUSH_AFTER_DRAW
77
78/* This is not available on non Windows hosts. */
79#ifndef D3D_RELEASE
80# define D3D_RELEASE(a_Ptr) do { if ((a_Ptr)) (a_Ptr)->Release(); (a_Ptr) = NULL; } while (0)
81#endif
82
83/** Fake ID for the backend DX context. The context creates all shared textures. */
84#define DX_CID_BACKEND UINT32_C(0xfffffffe)
85
86#define D3D_RELEASE_ARRAY(a_Count, a_papArray) do { \
87 for (uint32_t i = 0; i < (a_Count); ++i) \
88 D3D_RELEASE((a_papArray)[i]); \
89} while (0)
90
91typedef struct D3D11BLITTER
92{
93 ID3D11Device1 *pDevice;
94 ID3D11DeviceContext1 *pImmediateContext;
95
96 ID3D11VertexShader *pVertexShader;
97 ID3D11PixelShader *pPixelShader;
98 ID3D11SamplerState *pSamplerState;
99 ID3D11RasterizerState1 *pRasterizerState;
100 ID3D11BlendState1 *pBlendState;
101} D3D11BLITTER;
102
103typedef struct DXDEVICE
104{
105 ID3D11Device1 *pDevice; /* Device. */
106 ID3D11DeviceContext1 *pImmediateContext; /* Corresponding context. */
107 IDXGIFactory *pDxgiFactory; /* DXGI Factory. */
108 D3D_FEATURE_LEVEL FeatureLevel;
109
110 uint32_t MultisampleCountMask; /* 1 << (MSCount - 1) for MSCount = 2, 4, 8, 16, 32 */
111
112 ID3D11VideoDevice *pVideoDevice;
113 ID3D11VideoContext *pVideoContext;
114#ifdef DX_COMMON_STAGING_BUFFER
115 /* Staging buffer for transfer to surface buffers. */
116 ID3D11Buffer *pStagingBuffer; /* The staging buffer resource. */
117 uint32_t cbStagingBuffer; /* Current size of the staging buffer resource. */
118#endif
119
120 D3D11BLITTER Blitter; /* Blits one texture to another. */
121} DXDEVICE;
122
123/* Kind of a texture view. */
124typedef enum VMSVGA3DBACKVIEWTYPE
125{
126 VMSVGA3D_VIEWTYPE_NONE = 0,
127 VMSVGA3D_VIEWTYPE_RENDERTARGET = 1,
128 VMSVGA3D_VIEWTYPE_DEPTHSTENCIL = 2,
129 VMSVGA3D_VIEWTYPE_SHADERRESOURCE = 3,
130 VMSVGA3D_VIEWTYPE_UNORDEREDACCESS = 4,
131 VMSVGA3D_VIEWTYPE_VIDEODECODEROUTPUT = 5,
132 VMSVGA3D_VIEWTYPE_VIDEOPROCESSORINPUT = 6,
133 VMSVGA3D_VIEWTYPE_VIDEOPROCESSOROUTPUT = 7
134} VMSVGA3DBACKVIEWTYPE;
135
136/* Information about a texture view to track all created views:.
137 * when a surface is invalidated, then all views must deleted;
138 * when a view is deleted, then the view must be unlinked from the surface.
139 */
140typedef struct DXVIEWINFO
141{
142 uint32_t sid; /* Surface which the view was created for. */
143 uint32_t cid; /* DX context which created the view. */
144 uint32_t viewId; /* View id assigned by the guest. */
145 VMSVGA3DBACKVIEWTYPE enmViewType;
146} DXVIEWINFO;
147
148/* Context Object Table element for a texture view. */
149typedef struct DXVIEW
150{
151 uint32_t cid; /* DX context which created the view. */
152 uint32_t sid; /* Surface which the view was created for. */
153 uint32_t viewId; /* View id assigned by the guest. */
154 VMSVGA3DBACKVIEWTYPE enmViewType;
155
156 union
157 {
158 ID3D11View *pView; /* The view object. */
159 ID3D11RenderTargetView *pRenderTargetView;
160 ID3D11DepthStencilView *pDepthStencilView;
161 ID3D11ShaderResourceView *pShaderResourceView;
162 ID3D11UnorderedAccessView *pUnorderedAccessView;
163 ID3D11VideoDecoderOutputView *pVideoDecoderOutputView;
164 ID3D11VideoProcessorInputView *pVideoProcessorInputView;
165 ID3D11VideoProcessorOutputView *pVideoProcessorOutputView;
166 } u;
167
168 RTLISTNODE nodeSurfaceView; /* Views are linked to the surface. */
169} DXVIEW;
170
171/* What kind of resource has been created for the VMSVGA3D surface. */
172typedef enum VMSVGA3DBACKRESTYPE
173{
174 VMSVGA3D_RESTYPE_NONE = 0,
175 VMSVGA3D_RESTYPE_TEXTURE_1D = 1,
176 VMSVGA3D_RESTYPE_TEXTURE_2D = 2,
177 VMSVGA3D_RESTYPE_TEXTURE_CUBE = 3,
178 VMSVGA3D_RESTYPE_TEXTURE_3D = 4,
179 VMSVGA3D_RESTYPE_BUFFER = 5,
180} VMSVGA3DBACKRESTYPE;
181
182typedef struct VMSVGA3DBACKENDSURFACE
183{
184 VMSVGA3DBACKRESTYPE enmResType;
185 DXGI_FORMAT enmDxgiFormat;
186 union
187 {
188 ID3D11Resource *pResource;
189 ID3D11Texture1D *pTexture1D;
190 ID3D11Texture2D *pTexture2D;
191 ID3D11Texture3D *pTexture3D;
192 ID3D11Buffer *pBuffer;
193 } u;
194
195 /* For updates from memory. */
196 union /** @todo One per format. */
197 {
198 ID3D11Resource *pResource;
199 ID3D11Texture1D *pTexture1D;
200 ID3D11Texture2D *pTexture2D;
201 ID3D11Texture3D *pTexture3D;
202#ifndef DX_COMMON_STAGING_BUFFER
203 ID3D11Buffer *pBuffer;
204#endif
205 } dynamic;
206
207 /* For reading the texture content. */
208 union /** @todo One per format. */
209 {
210 ID3D11Resource *pResource;
211 ID3D11Texture1D *pTexture1D;
212 ID3D11Texture2D *pTexture2D;
213 ID3D11Texture3D *pTexture3D;
214#ifndef DX_COMMON_STAGING_BUFFER
215 ID3D11Buffer *pBuffer;
216#endif
217 } staging;
218
219 /* Screen targets are created as shared surfaces. */
220 HANDLE SharedHandle; /* The shared handle of this structure. */
221
222 /* DX context which last rendered to the texture.
223 * This is only for render targets and screen targets, which can be shared between contexts.
224 * The backend context (cid == DX_CID_BACKEND) can also be a drawing context.
225 */
226 uint32_t cidDrawing;
227
228 /** AVL tree containing DXSHAREDTEXTURE structures. */
229 AVLU32TREE SharedTextureTree;
230
231 /* Render target views, depth stencil views and shader resource views created for this texture or buffer. */
232 RTLISTANCHOR listView; /* DXVIEW */
233
234} VMSVGA3DBACKENDSURFACE;
235
236/* "The only resources that can be shared are 2D non-mipmapped textures." */
237typedef struct DXSHAREDTEXTURE
238{
239 AVLU32NODECORE Core; /* Key is context id which opened this texture. */
240 ID3D11Texture2D *pTexture; /* The opened shared texture. */
241 uint32_t sid; /* Surface id. */
242} DXSHAREDTEXTURE;
243
244
245typedef struct VMSVGAHWSCREEN
246{
247 ID3D11Texture2D *pTexture; /* Shared texture for the screen content. Only used as CopyResource target. */
248 IDXGIResource *pDxgiResource; /* Interface of the texture. */
249 IDXGIKeyedMutex *pDXGIKeyedMutex; /* Synchronization interface for the render device. */
250 HANDLE SharedHandle; /* The shared handle of this structure. */
251 uint32_t sidScreenTarget; /* The source surface for this screen. */
252} VMSVGAHWSCREEN;
253
254
255typedef struct DXELEMENTLAYOUT
256{
257 ID3D11InputLayout *pElementLayout;
258 uint32_t cElementDesc;
259 D3D11_INPUT_ELEMENT_DESC aElementDesc[32];
260} DXELEMENTLAYOUT;
261
262typedef struct DXSHADER
263{
264 SVGA3dShaderType enmShaderType;
265 union
266 {
267 ID3D11DeviceChild *pShader; /* All. */
268 ID3D11VertexShader *pVertexShader; /* SVGA3D_SHADERTYPE_VS */
269 ID3D11PixelShader *pPixelShader; /* SVGA3D_SHADERTYPE_PS */
270 ID3D11GeometryShader *pGeometryShader; /* SVGA3D_SHADERTYPE_GS */
271 ID3D11HullShader *pHullShader; /* SVGA3D_SHADERTYPE_HS */
272 ID3D11DomainShader *pDomainShader; /* SVGA3D_SHADERTYPE_DS */
273 ID3D11ComputeShader *pComputeShader; /* SVGA3D_SHADERTYPE_CS */
274 };
275 void *pvDXBC;
276 uint32_t cbDXBC;
277
278 uint32_t soid; /* Stream output declarations for geometry shaders. */
279
280 DXShaderInfo shaderInfo;
281} DXSHADER;
282
283typedef struct DXQUERY
284{
285 union
286 {
287 ID3D11Query *pQuery;
288 ID3D11Predicate *pPredicate;
289 };
290} DXQUERY;
291
292typedef struct DXVIDEOPROCESSOR
293{
294 ID3D11VideoProcessorEnumerator *pEnum;
295 ID3D11VideoProcessor *pVideoProcessor;
296} DXVIDEOPROCESSOR;
297
298typedef struct DXVIDEODECODER
299{
300 ID3D11VideoDecoder *pVideoDecoder;
301} DXVIDEODECODER;
302
303typedef struct DXSTREAMOUTPUT
304{
305 UINT cDeclarationEntry;
306 D3D11_SO_DECLARATION_ENTRY aDeclarationEntry[SVGA3D_MAX_STREAMOUT_DECLS];
307} DXSTREAMOUTPUT;
308
309typedef struct DXBOUNDVERTEXBUFFER
310{
311 ID3D11Buffer *pBuffer;
312 uint32_t stride;
313 uint32_t offset;
314} DXBOUNDVERTEXBUFFER;
315
316typedef struct DXBOUNDINDEXBUFFER
317{
318 ID3D11Buffer *pBuffer;
319 DXGI_FORMAT indexBufferFormat;
320 uint32_t indexBufferOffset;
321} DXBOUNDINDEXBUFFER;
322
323typedef struct DXBOUNDRESOURCES /* Currently bound resources. Mirror SVGADXContextMobFormat structure. */
324{
325 struct
326 {
327 ID3D11Buffer *constantBuffers[SVGA3D_DX_MAX_CONSTBUFFERS];
328 } shaderState[SVGA3D_NUM_SHADERTYPE];
329} DXBOUNDRESOURCES;
330
331
332typedef struct VMSVGA3DBACKENDDXCONTEXT
333{
334 DXDEVICE dxDevice; /* DX device interfaces for this context operations. */
335
336 /* Arrays for Context-Object Tables. Number of entries depends on COTable size. */
337 uint32_t cBlendState; /* Number of entries in the papBlendState array. */
338 uint32_t cDepthStencilState; /* papDepthStencilState */
339 uint32_t cSamplerState; /* papSamplerState */
340 uint32_t cRasterizerState; /* papRasterizerState */
341 uint32_t cElementLayout; /* paElementLayout */
342 uint32_t cRenderTargetView; /* paRenderTargetView */
343 uint32_t cDepthStencilView; /* paDepthStencilView */
344 uint32_t cShaderResourceView; /* paShaderResourceView */
345 uint32_t cQuery; /* paQuery */
346 uint32_t cShader; /* paShader */
347 uint32_t cStreamOutput; /* paStreamOutput */
348 uint32_t cUnorderedAccessView; /* paUnorderedAccessView */
349 ID3D11BlendState1 **papBlendState;
350 ID3D11DepthStencilState **papDepthStencilState;
351 ID3D11SamplerState **papSamplerState;
352 ID3D11RasterizerState1 **papRasterizerState;
353 DXELEMENTLAYOUT *paElementLayout;
354 DXVIEW *paRenderTargetView;
355 DXVIEW *paDepthStencilView;
356 DXVIEW *paShaderResourceView;
357 DXQUERY *paQuery;
358 DXSHADER *paShader;
359 DXSTREAMOUTPUT *paStreamOutput;
360 DXVIEW *paUnorderedAccessView;
361
362 uint32_t cVideoProcessor; /* paVideoProcessor */
363 uint32_t cVideoDecoderOutputView; /* paVideoDecoderOutputView */
364 uint32_t cVideoDecoder; /* paVideoDecoder */
365 uint32_t cVideoProcessorInputView; /* paVideoProcessorInputView */
366 uint32_t cVideoProcessorOutputView; /* paVideoProcessorOutputView */
367 DXVIDEOPROCESSOR *paVideoProcessor;
368 DXVIEW *paVideoDecoderOutputView;
369 DXVIDEODECODER *paVideoDecoder;
370 DXVIEW *paVideoProcessorInputView;
371 DXVIEW *paVideoProcessorOutputView;
372
373 uint32_t cSOTarget; /* How many SO targets are currently set (SetSOTargets) */
374
375 DXBOUNDRESOURCES resources;
376} VMSVGA3DBACKENDDXCONTEXT;
377
378/* Shader disassembler function. Optional. */
379typedef HRESULT FN_D3D_DISASSEMBLE(LPCVOID pSrcData, SIZE_T SrcDataSize, UINT Flags, LPCSTR szComments, ID3D10Blob **ppDisassembly);
380typedef FN_D3D_DISASSEMBLE *PFN_D3D_DISASSEMBLE;
381
382typedef struct VMSVGA3DBACKEND
383{
384 RTLDRMOD hD3D11;
385 PFN_D3D11_CREATE_DEVICE pfnD3D11CreateDevice;
386
387 RTLDRMOD hD3DCompiler;
388 PFN_D3D_DISASSEMBLE pfnD3DDisassemble;
389
390 DXDEVICE dxDevice; /* Device for the VMSVGA3D context independent operation. */
391 UINT VendorId;
392 UINT DeviceId;
393
394 SVGADXContextMobFormat svgaDXContext; /* Current state of pipeline. */
395
396 DXBOUNDRESOURCES resources; /* What is currently applied to the pipeline. */
397
398 bool fSingleDevice; /* Whether to use one DX device for all guest contexts. */
399
400 /** @todo Here a set of functions which do different job in single and multiple device modes. */
401} VMSVGA3DBACKEND;
402
403
404/* Static function prototypes. */
405static int dxDeviceFlush(DXDEVICE *pDevice);
406static int dxSetRenderTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext);
407static int dxSetCSUnorderedAccessViews(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext);
408static DECLCALLBACK(void) vmsvga3dBackSurfaceDestroy(PVGASTATECC pThisCC, bool fClearCOTableEntry, PVMSVGA3DSURFACE pSurface);
409static int dxDestroyShader(DXSHADER *pDXShader);
410static int dxDestroyQuery(DXQUERY *pDXQuery);
411static int dxReadBuffer(DXDEVICE *pDevice, ID3D11Buffer *pBuffer, UINT Offset, UINT Bytes, void **ppvData, uint32_t *pcbData);
412
413static int dxCreateVideoProcessor(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, VBSVGA3dVideoProcessorId videoProcessorId, VBSVGACOTableDXVideoProcessorEntry const *pEntry);
414static void dxDestroyVideoProcessor(DXVIDEOPROCESSOR *pDXVideoProcessor);
415static int dxCreateVideoDecoder(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, VBSVGA3dVideoDecoderId videoDecoderId, VBSVGACOTableDXVideoDecoderEntry const *pEntry);
416static void dxDestroyVideoDecoder(DXVIDEODECODER *pDXVideoDecoder);
417
418static HRESULT BlitInit(D3D11BLITTER *pBlitter, ID3D11Device1 *pDevice, ID3D11DeviceContext1 *pImmediateContext);
419static void BlitRelease(D3D11BLITTER *pBlitter);
420
421
422/* This is not available with the DXVK headers for some reason. */
423#ifndef RT_OS_WINDOWS
424typedef enum D3D11_TEXTURECUBE_FACE {
425 D3D11_TEXTURECUBE_FACE_POSITIVE_X,
426 D3D11_TEXTURECUBE_FACE_NEGATIVE_X,
427 D3D11_TEXTURECUBE_FACE_POSITIVE_Y,
428 D3D11_TEXTURECUBE_FACE_NEGATIVE_Y,
429 D3D11_TEXTURECUBE_FACE_POSITIVE_Z,
430 D3D11_TEXTURECUBE_FACE_NEGATIVE_Z
431} D3D11_TEXTURECUBE_FACE;
432#endif
433
434
435#if 0 /* unused */
436DECLINLINE(D3D11_TEXTURECUBE_FACE) vmsvga3dCubemapFaceFromIndex(uint32_t iFace)
437{
438 D3D11_TEXTURECUBE_FACE Face;
439 switch (iFace)
440 {
441 case 0: Face = D3D11_TEXTURECUBE_FACE_POSITIVE_X; break;
442 case 1: Face = D3D11_TEXTURECUBE_FACE_NEGATIVE_X; break;
443 case 2: Face = D3D11_TEXTURECUBE_FACE_POSITIVE_Y; break;
444 case 3: Face = D3D11_TEXTURECUBE_FACE_NEGATIVE_Y; break;
445 case 4: Face = D3D11_TEXTURECUBE_FACE_POSITIVE_Z; break;
446 default:
447 case 5: Face = D3D11_TEXTURECUBE_FACE_NEGATIVE_Z; break;
448 }
449 return Face;
450}
451#endif
452
453/* This is to workaround issues with X8 formats, because they can't be used in some operations. */
454#define DX_REPLACE_X8_WITH_A8
455static DXGI_FORMAT vmsvgaDXSurfaceFormat2Dxgi(SVGA3dSurfaceFormat format)
456{
457 /* Ensure that correct headers are used.
458 * SVGA3D_AYUV was equal to 45, then replaced with SVGA3D_FORMAT_DEAD2 = 45, and redefined as SVGA3D_AYUV = 152.
459 */
460 AssertCompile(SVGA3D_AYUV == 152);
461
462#define DXGI_FORMAT_ DXGI_FORMAT_UNKNOWN
463 /** @todo More formats. */
464 switch (format)
465 {
466#ifdef DX_REPLACE_X8_WITH_A8
467 case SVGA3D_X8R8G8B8: return DXGI_FORMAT_B8G8R8A8_UNORM;
468#else
469 case SVGA3D_X8R8G8B8: return DXGI_FORMAT_B8G8R8X8_UNORM;
470#endif
471 case SVGA3D_A8R8G8B8: return DXGI_FORMAT_B8G8R8A8_UNORM;
472 case SVGA3D_R5G6B5: return DXGI_FORMAT_B5G6R5_UNORM;
473 case SVGA3D_X1R5G5B5: return DXGI_FORMAT_B5G5R5A1_UNORM;
474 case SVGA3D_A1R5G5B5: return DXGI_FORMAT_B5G5R5A1_UNORM;
475 case SVGA3D_A4R4G4B4: break; // 11.1 return DXGI_FORMAT_B4G4R4A4_UNORM;
476 case SVGA3D_Z_D32: break;
477 case SVGA3D_Z_D16: return DXGI_FORMAT_D16_UNORM;
478 case SVGA3D_Z_D24S8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
479 case SVGA3D_Z_D15S1: break;
480 case SVGA3D_LUMINANCE8: return DXGI_FORMAT_;
481 case SVGA3D_LUMINANCE4_ALPHA4: return DXGI_FORMAT_;
482 case SVGA3D_LUMINANCE16: return DXGI_FORMAT_;
483 case SVGA3D_LUMINANCE8_ALPHA8: return DXGI_FORMAT_;
484 case SVGA3D_DXT1: return DXGI_FORMAT_;
485 case SVGA3D_DXT2: return DXGI_FORMAT_;
486 case SVGA3D_DXT3: return DXGI_FORMAT_;
487 case SVGA3D_DXT4: return DXGI_FORMAT_;
488 case SVGA3D_DXT5: return DXGI_FORMAT_;
489 case SVGA3D_BUMPU8V8: return DXGI_FORMAT_;
490 case SVGA3D_BUMPL6V5U5: return DXGI_FORMAT_;
491 case SVGA3D_BUMPX8L8V8U8: return DXGI_FORMAT_;
492 case SVGA3D_FORMAT_DEAD1: break;
493 case SVGA3D_ARGB_S10E5: return DXGI_FORMAT_;
494 case SVGA3D_ARGB_S23E8: return DXGI_FORMAT_;
495 case SVGA3D_A2R10G10B10: return DXGI_FORMAT_;
496 case SVGA3D_V8U8: return DXGI_FORMAT_;
497 case SVGA3D_Q8W8V8U8: return DXGI_FORMAT_;
498 case SVGA3D_CxV8U8: return DXGI_FORMAT_;
499 case SVGA3D_X8L8V8U8: return DXGI_FORMAT_;
500 case SVGA3D_A2W10V10U10: return DXGI_FORMAT_;
501 case SVGA3D_ALPHA8: return DXGI_FORMAT_;
502 case SVGA3D_R_S10E5: return DXGI_FORMAT_;
503 case SVGA3D_R_S23E8: return DXGI_FORMAT_;
504 case SVGA3D_RG_S10E5: return DXGI_FORMAT_;
505 case SVGA3D_RG_S23E8: return DXGI_FORMAT_;
506 case SVGA3D_BUFFER: return DXGI_FORMAT_;
507 case SVGA3D_Z_D24X8: return DXGI_FORMAT_;
508 case SVGA3D_V16U16: return DXGI_FORMAT_;
509 case SVGA3D_G16R16: return DXGI_FORMAT_;
510 case SVGA3D_A16B16G16R16: return DXGI_FORMAT_;
511 case SVGA3D_UYVY: return DXGI_FORMAT_;
512 case SVGA3D_YUY2: return DXGI_FORMAT_YUY2;
513 case SVGA3D_NV12: return DXGI_FORMAT_NV12;
514 case SVGA3D_FORMAT_DEAD2: break; /* Old SVGA3D_AYUV */
515 case SVGA3D_R32G32B32A32_TYPELESS: return DXGI_FORMAT_R32G32B32A32_TYPELESS;
516 case SVGA3D_R32G32B32A32_UINT: return DXGI_FORMAT_R32G32B32A32_UINT;
517 case SVGA3D_R32G32B32A32_SINT: return DXGI_FORMAT_R32G32B32A32_SINT;
518 case SVGA3D_R32G32B32_TYPELESS: return DXGI_FORMAT_R32G32B32_TYPELESS;
519 case SVGA3D_R32G32B32_FLOAT: return DXGI_FORMAT_R32G32B32_FLOAT;
520 case SVGA3D_R32G32B32_UINT: return DXGI_FORMAT_R32G32B32_UINT;
521 case SVGA3D_R32G32B32_SINT: return DXGI_FORMAT_R32G32B32_SINT;
522 case SVGA3D_R16G16B16A16_TYPELESS: return DXGI_FORMAT_R16G16B16A16_TYPELESS;
523 case SVGA3D_R16G16B16A16_UINT: return DXGI_FORMAT_R16G16B16A16_UINT;
524 case SVGA3D_R16G16B16A16_SNORM: return DXGI_FORMAT_R16G16B16A16_SNORM;
525 case SVGA3D_R16G16B16A16_SINT: return DXGI_FORMAT_R16G16B16A16_SINT;
526 case SVGA3D_R32G32_TYPELESS: return DXGI_FORMAT_R32G32_TYPELESS;
527 case SVGA3D_R32G32_UINT: return DXGI_FORMAT_R32G32_UINT;
528 case SVGA3D_R32G32_SINT: return DXGI_FORMAT_R32G32_SINT;
529 case SVGA3D_R32G8X24_TYPELESS: return DXGI_FORMAT_R32G8X24_TYPELESS;
530 case SVGA3D_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
531 case SVGA3D_R32_FLOAT_X8X24: return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
532 case SVGA3D_X32_G8X24_UINT: return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
533 case SVGA3D_R10G10B10A2_TYPELESS: return DXGI_FORMAT_R10G10B10A2_TYPELESS;
534 case SVGA3D_R10G10B10A2_UINT: return DXGI_FORMAT_R10G10B10A2_UINT;
535 case SVGA3D_R11G11B10_FLOAT: return DXGI_FORMAT_R11G11B10_FLOAT;
536 case SVGA3D_R8G8B8A8_TYPELESS: return DXGI_FORMAT_R8G8B8A8_TYPELESS;
537 case SVGA3D_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM;
538 case SVGA3D_R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
539 case SVGA3D_R8G8B8A8_UINT: return DXGI_FORMAT_R8G8B8A8_UINT;
540 case SVGA3D_R8G8B8A8_SINT: return DXGI_FORMAT_R8G8B8A8_SINT;
541 case SVGA3D_R16G16_TYPELESS: return DXGI_FORMAT_R16G16_TYPELESS;
542 case SVGA3D_R16G16_UINT: return DXGI_FORMAT_R16G16_UINT;
543 case SVGA3D_R16G16_SINT: return DXGI_FORMAT_R16G16_SINT;
544 case SVGA3D_R32_TYPELESS: return DXGI_FORMAT_R32_TYPELESS;
545 case SVGA3D_D32_FLOAT: return DXGI_FORMAT_D32_FLOAT;
546 case SVGA3D_R32_UINT: return DXGI_FORMAT_R32_UINT;
547 case SVGA3D_R32_SINT: return DXGI_FORMAT_R32_SINT;
548 case SVGA3D_R24G8_TYPELESS: return DXGI_FORMAT_R24G8_TYPELESS;
549 case SVGA3D_D24_UNORM_S8_UINT: return DXGI_FORMAT_D24_UNORM_S8_UINT;
550 case SVGA3D_R24_UNORM_X8: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
551 case SVGA3D_X24_G8_UINT: return DXGI_FORMAT_X24_TYPELESS_G8_UINT;
552 case SVGA3D_R8G8_TYPELESS: return DXGI_FORMAT_R8G8_TYPELESS;
553 case SVGA3D_R8G8_UNORM: return DXGI_FORMAT_R8G8_UNORM;
554 case SVGA3D_R8G8_UINT: return DXGI_FORMAT_R8G8_UINT;
555 case SVGA3D_R8G8_SINT: return DXGI_FORMAT_R8G8_SINT;
556 case SVGA3D_R16_TYPELESS: return DXGI_FORMAT_R16_TYPELESS;
557 case SVGA3D_R16_UNORM: return DXGI_FORMAT_R16_UNORM;
558 case SVGA3D_R16_UINT: return DXGI_FORMAT_R16_UINT;
559 case SVGA3D_R16_SNORM: return DXGI_FORMAT_R16_SNORM;
560 case SVGA3D_R16_SINT: return DXGI_FORMAT_R16_SINT;
561 case SVGA3D_R8_TYPELESS: return DXGI_FORMAT_R8_TYPELESS;
562 case SVGA3D_R8_UNORM: return DXGI_FORMAT_R8_UNORM;
563 case SVGA3D_R8_UINT: return DXGI_FORMAT_R8_UINT;
564 case SVGA3D_R8_SNORM: return DXGI_FORMAT_R8_SNORM;
565 case SVGA3D_R8_SINT: return DXGI_FORMAT_R8_SINT;
566 case SVGA3D_P8: break;
567 case SVGA3D_R9G9B9E5_SHAREDEXP: return DXGI_FORMAT_R9G9B9E5_SHAREDEXP;
568 case SVGA3D_R8G8_B8G8_UNORM: return DXGI_FORMAT_R8G8_B8G8_UNORM;
569 case SVGA3D_G8R8_G8B8_UNORM: return DXGI_FORMAT_G8R8_G8B8_UNORM;
570 case SVGA3D_BC1_TYPELESS: return DXGI_FORMAT_BC1_TYPELESS;
571 case SVGA3D_BC1_UNORM_SRGB: return DXGI_FORMAT_BC1_UNORM_SRGB;
572 case SVGA3D_BC2_TYPELESS: return DXGI_FORMAT_BC2_TYPELESS;
573 case SVGA3D_BC2_UNORM_SRGB: return DXGI_FORMAT_BC2_UNORM_SRGB;
574 case SVGA3D_BC3_TYPELESS: return DXGI_FORMAT_BC3_TYPELESS;
575 case SVGA3D_BC3_UNORM_SRGB: return DXGI_FORMAT_BC3_UNORM_SRGB;
576 case SVGA3D_BC4_TYPELESS: return DXGI_FORMAT_BC4_TYPELESS;
577 case SVGA3D_ATI1: break;
578 case SVGA3D_BC4_SNORM: return DXGI_FORMAT_BC4_SNORM;
579 case SVGA3D_BC5_TYPELESS: return DXGI_FORMAT_BC5_TYPELESS;
580 case SVGA3D_ATI2: break;
581 case SVGA3D_BC5_SNORM: return DXGI_FORMAT_BC5_SNORM;
582 case SVGA3D_R10G10B10_XR_BIAS_A2_UNORM: return DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM;
583 case SVGA3D_B8G8R8A8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_TYPELESS;
584 case SVGA3D_B8G8R8A8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
585#ifdef DX_REPLACE_X8_WITH_A8
586 case SVGA3D_B8G8R8X8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_TYPELESS;
587 case SVGA3D_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
588#else
589 case SVGA3D_B8G8R8X8_TYPELESS: return DXGI_FORMAT_B8G8R8X8_TYPELESS;
590 case SVGA3D_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
591#endif
592 case SVGA3D_Z_DF16: break;
593 case SVGA3D_Z_DF24: break;
594 case SVGA3D_Z_D24S8_INT: return DXGI_FORMAT_D24_UNORM_S8_UINT;
595 case SVGA3D_YV12: break;
596 case SVGA3D_R32G32B32A32_FLOAT: return DXGI_FORMAT_R32G32B32A32_FLOAT;
597 case SVGA3D_R16G16B16A16_FLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT;
598 case SVGA3D_R16G16B16A16_UNORM: return DXGI_FORMAT_R16G16B16A16_UNORM;
599 case SVGA3D_R32G32_FLOAT: return DXGI_FORMAT_R32G32_FLOAT;
600 case SVGA3D_R10G10B10A2_UNORM: return DXGI_FORMAT_R10G10B10A2_UNORM;
601 case SVGA3D_R8G8B8A8_SNORM: return DXGI_FORMAT_R8G8B8A8_SNORM;
602 case SVGA3D_R16G16_FLOAT: return DXGI_FORMAT_R16G16_FLOAT;
603 case SVGA3D_R16G16_UNORM: return DXGI_FORMAT_R16G16_UNORM;
604 case SVGA3D_R16G16_SNORM: return DXGI_FORMAT_R16G16_SNORM;
605 case SVGA3D_R32_FLOAT: return DXGI_FORMAT_R32_FLOAT;
606 case SVGA3D_R8G8_SNORM: return DXGI_FORMAT_R8G8_SNORM;
607 case SVGA3D_R16_FLOAT: return DXGI_FORMAT_R16_FLOAT;
608 case SVGA3D_D16_UNORM: return DXGI_FORMAT_D16_UNORM;
609 case SVGA3D_A8_UNORM: return DXGI_FORMAT_A8_UNORM;
610 case SVGA3D_BC1_UNORM: return DXGI_FORMAT_BC1_UNORM;
611 case SVGA3D_BC2_UNORM: return DXGI_FORMAT_BC2_UNORM;
612 case SVGA3D_BC3_UNORM: return DXGI_FORMAT_BC3_UNORM;
613 case SVGA3D_B5G6R5_UNORM: return DXGI_FORMAT_B5G6R5_UNORM;
614 case SVGA3D_B5G5R5A1_UNORM: return DXGI_FORMAT_B5G5R5A1_UNORM;
615 case SVGA3D_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM;
616#ifdef DX_REPLACE_X8_WITH_A8
617 case SVGA3D_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM;
618#else
619 case SVGA3D_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8X8_UNORM;
620#endif
621 case SVGA3D_BC4_UNORM: return DXGI_FORMAT_BC4_UNORM;
622 case SVGA3D_BC5_UNORM: return DXGI_FORMAT_BC5_UNORM;
623
624 case SVGA3D_B4G4R4A4_UNORM: return DXGI_FORMAT_;
625 case SVGA3D_BC6H_TYPELESS: return DXGI_FORMAT_BC6H_TYPELESS;
626 case SVGA3D_BC6H_UF16: return DXGI_FORMAT_BC6H_UF16;
627 case SVGA3D_BC6H_SF16: return DXGI_FORMAT_BC6H_SF16;
628 case SVGA3D_BC7_TYPELESS: return DXGI_FORMAT_BC7_TYPELESS;
629 case SVGA3D_BC7_UNORM: return DXGI_FORMAT_BC7_UNORM;
630 case SVGA3D_BC7_UNORM_SRGB: return DXGI_FORMAT_BC7_UNORM_SRGB;
631 case SVGA3D_AYUV: return DXGI_FORMAT_AYUV;
632
633 case SVGA3D_FORMAT_INVALID:
634 case SVGA3D_FORMAT_MAX: break;
635 }
636 // AssertFailed();
637 return DXGI_FORMAT_UNKNOWN;
638#undef DXGI_FORMAT_
639}
640
641
642static SVGA3dSurfaceFormat vmsvgaDXDevCapSurfaceFmt2Format(SVGA3dDevCapIndex enmDevCap)
643{
644 switch (enmDevCap)
645 {
646 case SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8: return SVGA3D_X8R8G8B8;
647 case SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8: return SVGA3D_A8R8G8B8;
648 case SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10: return SVGA3D_A2R10G10B10;
649 case SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5: return SVGA3D_X1R5G5B5;
650 case SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5: return SVGA3D_A1R5G5B5;
651 case SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4: return SVGA3D_A4R4G4B4;
652 case SVGA3D_DEVCAP_SURFACEFMT_R5G6B5: return SVGA3D_R5G6B5;
653 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16: return SVGA3D_LUMINANCE16;
654 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8: return SVGA3D_LUMINANCE8_ALPHA8;
655 case SVGA3D_DEVCAP_SURFACEFMT_ALPHA8: return SVGA3D_ALPHA8;
656 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8: return SVGA3D_LUMINANCE8;
657 case SVGA3D_DEVCAP_SURFACEFMT_Z_D16: return SVGA3D_Z_D16;
658 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8: return SVGA3D_Z_D24S8;
659 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8: return SVGA3D_Z_D24X8;
660 case SVGA3D_DEVCAP_SURFACEFMT_DXT1: return SVGA3D_DXT1;
661 case SVGA3D_DEVCAP_SURFACEFMT_DXT2: return SVGA3D_DXT2;
662 case SVGA3D_DEVCAP_SURFACEFMT_DXT3: return SVGA3D_DXT3;
663 case SVGA3D_DEVCAP_SURFACEFMT_DXT4: return SVGA3D_DXT4;
664 case SVGA3D_DEVCAP_SURFACEFMT_DXT5: return SVGA3D_DXT5;
665 case SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8: return SVGA3D_BUMPX8L8V8U8;
666 case SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10: return SVGA3D_A2W10V10U10;
667 case SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8: return SVGA3D_BUMPU8V8;
668 case SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8: return SVGA3D_Q8W8V8U8;
669 case SVGA3D_DEVCAP_SURFACEFMT_CxV8U8: return SVGA3D_CxV8U8;
670 case SVGA3D_DEVCAP_SURFACEFMT_R_S10E5: return SVGA3D_R_S10E5;
671 case SVGA3D_DEVCAP_SURFACEFMT_R_S23E8: return SVGA3D_R_S23E8;
672 case SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5: return SVGA3D_RG_S10E5;
673 case SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8: return SVGA3D_RG_S23E8;
674 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5: return SVGA3D_ARGB_S10E5;
675 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8: return SVGA3D_ARGB_S23E8;
676 case SVGA3D_DEVCAP_SURFACEFMT_V16U16: return SVGA3D_V16U16;
677 case SVGA3D_DEVCAP_SURFACEFMT_G16R16: return SVGA3D_G16R16;
678 case SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16: return SVGA3D_A16B16G16R16;
679 case SVGA3D_DEVCAP_SURFACEFMT_UYVY: return SVGA3D_UYVY;
680 case SVGA3D_DEVCAP_SURFACEFMT_YUY2: return SVGA3D_YUY2;
681 case SVGA3D_DEVCAP_SURFACEFMT_NV12: return SVGA3D_NV12;
682 case SVGA3D_DEVCAP_DEAD10: return SVGA3D_FORMAT_DEAD2; /* SVGA3D_DEVCAP_SURFACEFMT_AYUV -> SVGA3D_AYUV */
683 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF16: return SVGA3D_Z_DF16;
684 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF24: return SVGA3D_Z_DF24;
685 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT: return SVGA3D_Z_D24S8_INT;
686 case SVGA3D_DEVCAP_SURFACEFMT_ATI1: return SVGA3D_ATI1;
687 case SVGA3D_DEVCAP_SURFACEFMT_ATI2: return SVGA3D_ATI2;
688 case SVGA3D_DEVCAP_SURFACEFMT_YV12: return SVGA3D_YV12;
689 default:
690 AssertFailed();
691 break;
692 }
693 return SVGA3D_FORMAT_INVALID;
694}
695
696
697static SVGA3dSurfaceFormat vmsvgaDXDevCapDxfmt2Format(SVGA3dDevCapIndex enmDevCap)
698{
699 switch (enmDevCap)
700 {
701 case SVGA3D_DEVCAP_DXFMT_X8R8G8B8: return SVGA3D_X8R8G8B8;
702 case SVGA3D_DEVCAP_DXFMT_A8R8G8B8: return SVGA3D_A8R8G8B8;
703 case SVGA3D_DEVCAP_DXFMT_R5G6B5: return SVGA3D_R5G6B5;
704 case SVGA3D_DEVCAP_DXFMT_X1R5G5B5: return SVGA3D_X1R5G5B5;
705 case SVGA3D_DEVCAP_DXFMT_A1R5G5B5: return SVGA3D_A1R5G5B5;
706 case SVGA3D_DEVCAP_DXFMT_A4R4G4B4: return SVGA3D_A4R4G4B4;
707 case SVGA3D_DEVCAP_DXFMT_Z_D32: return SVGA3D_Z_D32;
708 case SVGA3D_DEVCAP_DXFMT_Z_D16: return SVGA3D_Z_D16;
709 case SVGA3D_DEVCAP_DXFMT_Z_D24S8: return SVGA3D_Z_D24S8;
710 case SVGA3D_DEVCAP_DXFMT_Z_D15S1: return SVGA3D_Z_D15S1;
711 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8: return SVGA3D_LUMINANCE8;
712 case SVGA3D_DEVCAP_DXFMT_LUMINANCE4_ALPHA4: return SVGA3D_LUMINANCE4_ALPHA4;
713 case SVGA3D_DEVCAP_DXFMT_LUMINANCE16: return SVGA3D_LUMINANCE16;
714 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8_ALPHA8: return SVGA3D_LUMINANCE8_ALPHA8;
715 case SVGA3D_DEVCAP_DXFMT_DXT1: return SVGA3D_DXT1;
716 case SVGA3D_DEVCAP_DXFMT_DXT2: return SVGA3D_DXT2;
717 case SVGA3D_DEVCAP_DXFMT_DXT3: return SVGA3D_DXT3;
718 case SVGA3D_DEVCAP_DXFMT_DXT4: return SVGA3D_DXT4;
719 case SVGA3D_DEVCAP_DXFMT_DXT5: return SVGA3D_DXT5;
720 case SVGA3D_DEVCAP_DXFMT_BUMPU8V8: return SVGA3D_BUMPU8V8;
721 case SVGA3D_DEVCAP_DXFMT_BUMPL6V5U5: return SVGA3D_BUMPL6V5U5;
722 case SVGA3D_DEVCAP_DXFMT_BUMPX8L8V8U8: return SVGA3D_BUMPX8L8V8U8;
723 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD1: return SVGA3D_FORMAT_DEAD1;
724 case SVGA3D_DEVCAP_DXFMT_ARGB_S10E5: return SVGA3D_ARGB_S10E5;
725 case SVGA3D_DEVCAP_DXFMT_ARGB_S23E8: return SVGA3D_ARGB_S23E8;
726 case SVGA3D_DEVCAP_DXFMT_A2R10G10B10: return SVGA3D_A2R10G10B10;
727 case SVGA3D_DEVCAP_DXFMT_V8U8: return SVGA3D_V8U8;
728 case SVGA3D_DEVCAP_DXFMT_Q8W8V8U8: return SVGA3D_Q8W8V8U8;
729 case SVGA3D_DEVCAP_DXFMT_CxV8U8: return SVGA3D_CxV8U8;
730 case SVGA3D_DEVCAP_DXFMT_X8L8V8U8: return SVGA3D_X8L8V8U8;
731 case SVGA3D_DEVCAP_DXFMT_A2W10V10U10: return SVGA3D_A2W10V10U10;
732 case SVGA3D_DEVCAP_DXFMT_ALPHA8: return SVGA3D_ALPHA8;
733 case SVGA3D_DEVCAP_DXFMT_R_S10E5: return SVGA3D_R_S10E5;
734 case SVGA3D_DEVCAP_DXFMT_R_S23E8: return SVGA3D_R_S23E8;
735 case SVGA3D_DEVCAP_DXFMT_RG_S10E5: return SVGA3D_RG_S10E5;
736 case SVGA3D_DEVCAP_DXFMT_RG_S23E8: return SVGA3D_RG_S23E8;
737 case SVGA3D_DEVCAP_DXFMT_BUFFER: return SVGA3D_BUFFER;
738 case SVGA3D_DEVCAP_DXFMT_Z_D24X8: return SVGA3D_Z_D24X8;
739 case SVGA3D_DEVCAP_DXFMT_V16U16: return SVGA3D_V16U16;
740 case SVGA3D_DEVCAP_DXFMT_G16R16: return SVGA3D_G16R16;
741 case SVGA3D_DEVCAP_DXFMT_A16B16G16R16: return SVGA3D_A16B16G16R16;
742 case SVGA3D_DEVCAP_DXFMT_UYVY: return SVGA3D_UYVY;
743 case SVGA3D_DEVCAP_DXFMT_YUY2: return SVGA3D_YUY2;
744 case SVGA3D_DEVCAP_DXFMT_NV12: return SVGA3D_NV12;
745 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD2: return SVGA3D_FORMAT_DEAD2; /* SVGA3D_DEVCAP_DXFMT_AYUV -> SVGA3D_AYUV */
746 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_TYPELESS: return SVGA3D_R32G32B32A32_TYPELESS;
747 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_UINT: return SVGA3D_R32G32B32A32_UINT;
748 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_SINT: return SVGA3D_R32G32B32A32_SINT;
749 case SVGA3D_DEVCAP_DXFMT_R32G32B32_TYPELESS: return SVGA3D_R32G32B32_TYPELESS;
750 case SVGA3D_DEVCAP_DXFMT_R32G32B32_FLOAT: return SVGA3D_R32G32B32_FLOAT;
751 case SVGA3D_DEVCAP_DXFMT_R32G32B32_UINT: return SVGA3D_R32G32B32_UINT;
752 case SVGA3D_DEVCAP_DXFMT_R32G32B32_SINT: return SVGA3D_R32G32B32_SINT;
753 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_TYPELESS: return SVGA3D_R16G16B16A16_TYPELESS;
754 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UINT: return SVGA3D_R16G16B16A16_UINT;
755 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SNORM: return SVGA3D_R16G16B16A16_SNORM;
756 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SINT: return SVGA3D_R16G16B16A16_SINT;
757 case SVGA3D_DEVCAP_DXFMT_R32G32_TYPELESS: return SVGA3D_R32G32_TYPELESS;
758 case SVGA3D_DEVCAP_DXFMT_R32G32_UINT: return SVGA3D_R32G32_UINT;
759 case SVGA3D_DEVCAP_DXFMT_R32G32_SINT: return SVGA3D_R32G32_SINT;
760 case SVGA3D_DEVCAP_DXFMT_R32G8X24_TYPELESS: return SVGA3D_R32G8X24_TYPELESS;
761 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT_S8X24_UINT: return SVGA3D_D32_FLOAT_S8X24_UINT;
762 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT_X8X24: return SVGA3D_R32_FLOAT_X8X24;
763 case SVGA3D_DEVCAP_DXFMT_X32_G8X24_UINT: return SVGA3D_X32_G8X24_UINT;
764 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_TYPELESS: return SVGA3D_R10G10B10A2_TYPELESS;
765 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UINT: return SVGA3D_R10G10B10A2_UINT;
766 case SVGA3D_DEVCAP_DXFMT_R11G11B10_FLOAT: return SVGA3D_R11G11B10_FLOAT;
767 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_TYPELESS: return SVGA3D_R8G8B8A8_TYPELESS;
768 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM: return SVGA3D_R8G8B8A8_UNORM;
769 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM_SRGB: return SVGA3D_R8G8B8A8_UNORM_SRGB;
770 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UINT: return SVGA3D_R8G8B8A8_UINT;
771 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SINT: return SVGA3D_R8G8B8A8_SINT;
772 case SVGA3D_DEVCAP_DXFMT_R16G16_TYPELESS: return SVGA3D_R16G16_TYPELESS;
773 case SVGA3D_DEVCAP_DXFMT_R16G16_UINT: return SVGA3D_R16G16_UINT;
774 case SVGA3D_DEVCAP_DXFMT_R16G16_SINT: return SVGA3D_R16G16_SINT;
775 case SVGA3D_DEVCAP_DXFMT_R32_TYPELESS: return SVGA3D_R32_TYPELESS;
776 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT: return SVGA3D_D32_FLOAT;
777 case SVGA3D_DEVCAP_DXFMT_R32_UINT: return SVGA3D_R32_UINT;
778 case SVGA3D_DEVCAP_DXFMT_R32_SINT: return SVGA3D_R32_SINT;
779 case SVGA3D_DEVCAP_DXFMT_R24G8_TYPELESS: return SVGA3D_R24G8_TYPELESS;
780 case SVGA3D_DEVCAP_DXFMT_D24_UNORM_S8_UINT: return SVGA3D_D24_UNORM_S8_UINT;
781 case SVGA3D_DEVCAP_DXFMT_R24_UNORM_X8: return SVGA3D_R24_UNORM_X8;
782 case SVGA3D_DEVCAP_DXFMT_X24_G8_UINT: return SVGA3D_X24_G8_UINT;
783 case SVGA3D_DEVCAP_DXFMT_R8G8_TYPELESS: return SVGA3D_R8G8_TYPELESS;
784 case SVGA3D_DEVCAP_DXFMT_R8G8_UNORM: return SVGA3D_R8G8_UNORM;
785 case SVGA3D_DEVCAP_DXFMT_R8G8_UINT: return SVGA3D_R8G8_UINT;
786 case SVGA3D_DEVCAP_DXFMT_R8G8_SINT: return SVGA3D_R8G8_SINT;
787 case SVGA3D_DEVCAP_DXFMT_R16_TYPELESS: return SVGA3D_R16_TYPELESS;
788 case SVGA3D_DEVCAP_DXFMT_R16_UNORM: return SVGA3D_R16_UNORM;
789 case SVGA3D_DEVCAP_DXFMT_R16_UINT: return SVGA3D_R16_UINT;
790 case SVGA3D_DEVCAP_DXFMT_R16_SNORM: return SVGA3D_R16_SNORM;
791 case SVGA3D_DEVCAP_DXFMT_R16_SINT: return SVGA3D_R16_SINT;
792 case SVGA3D_DEVCAP_DXFMT_R8_TYPELESS: return SVGA3D_R8_TYPELESS;
793 case SVGA3D_DEVCAP_DXFMT_R8_UNORM: return SVGA3D_R8_UNORM;
794 case SVGA3D_DEVCAP_DXFMT_R8_UINT: return SVGA3D_R8_UINT;
795 case SVGA3D_DEVCAP_DXFMT_R8_SNORM: return SVGA3D_R8_SNORM;
796 case SVGA3D_DEVCAP_DXFMT_R8_SINT: return SVGA3D_R8_SINT;
797 case SVGA3D_DEVCAP_DXFMT_P8: return SVGA3D_P8;
798 case SVGA3D_DEVCAP_DXFMT_R9G9B9E5_SHAREDEXP: return SVGA3D_R9G9B9E5_SHAREDEXP;
799 case SVGA3D_DEVCAP_DXFMT_R8G8_B8G8_UNORM: return SVGA3D_R8G8_B8G8_UNORM;
800 case SVGA3D_DEVCAP_DXFMT_G8R8_G8B8_UNORM: return SVGA3D_G8R8_G8B8_UNORM;
801 case SVGA3D_DEVCAP_DXFMT_BC1_TYPELESS: return SVGA3D_BC1_TYPELESS;
802 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM_SRGB: return SVGA3D_BC1_UNORM_SRGB;
803 case SVGA3D_DEVCAP_DXFMT_BC2_TYPELESS: return SVGA3D_BC2_TYPELESS;
804 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM_SRGB: return SVGA3D_BC2_UNORM_SRGB;
805 case SVGA3D_DEVCAP_DXFMT_BC3_TYPELESS: return SVGA3D_BC3_TYPELESS;
806 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM_SRGB: return SVGA3D_BC3_UNORM_SRGB;
807 case SVGA3D_DEVCAP_DXFMT_BC4_TYPELESS: return SVGA3D_BC4_TYPELESS;
808 case SVGA3D_DEVCAP_DXFMT_ATI1: return SVGA3D_ATI1;
809 case SVGA3D_DEVCAP_DXFMT_BC4_SNORM: return SVGA3D_BC4_SNORM;
810 case SVGA3D_DEVCAP_DXFMT_BC5_TYPELESS: return SVGA3D_BC5_TYPELESS;
811 case SVGA3D_DEVCAP_DXFMT_ATI2: return SVGA3D_ATI2;
812 case SVGA3D_DEVCAP_DXFMT_BC5_SNORM: return SVGA3D_BC5_SNORM;
813 case SVGA3D_DEVCAP_DXFMT_R10G10B10_XR_BIAS_A2_UNORM: return SVGA3D_R10G10B10_XR_BIAS_A2_UNORM;
814 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_TYPELESS: return SVGA3D_B8G8R8A8_TYPELESS;
815 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM_SRGB: return SVGA3D_B8G8R8A8_UNORM_SRGB;
816 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_TYPELESS: return SVGA3D_B8G8R8X8_TYPELESS;
817 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM_SRGB: return SVGA3D_B8G8R8X8_UNORM_SRGB;
818 case SVGA3D_DEVCAP_DXFMT_Z_DF16: return SVGA3D_Z_DF16;
819 case SVGA3D_DEVCAP_DXFMT_Z_DF24: return SVGA3D_Z_DF24;
820 case SVGA3D_DEVCAP_DXFMT_Z_D24S8_INT: return SVGA3D_Z_D24S8_INT;
821 case SVGA3D_DEVCAP_DXFMT_YV12: return SVGA3D_YV12;
822 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_FLOAT: return SVGA3D_R32G32B32A32_FLOAT;
823 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_FLOAT: return SVGA3D_R16G16B16A16_FLOAT;
824 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UNORM: return SVGA3D_R16G16B16A16_UNORM;
825 case SVGA3D_DEVCAP_DXFMT_R32G32_FLOAT: return SVGA3D_R32G32_FLOAT;
826 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UNORM: return SVGA3D_R10G10B10A2_UNORM;
827 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SNORM: return SVGA3D_R8G8B8A8_SNORM;
828 case SVGA3D_DEVCAP_DXFMT_R16G16_FLOAT: return SVGA3D_R16G16_FLOAT;
829 case SVGA3D_DEVCAP_DXFMT_R16G16_UNORM: return SVGA3D_R16G16_UNORM;
830 case SVGA3D_DEVCAP_DXFMT_R16G16_SNORM: return SVGA3D_R16G16_SNORM;
831 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT: return SVGA3D_R32_FLOAT;
832 case SVGA3D_DEVCAP_DXFMT_R8G8_SNORM: return SVGA3D_R8G8_SNORM;
833 case SVGA3D_DEVCAP_DXFMT_R16_FLOAT: return SVGA3D_R16_FLOAT;
834 case SVGA3D_DEVCAP_DXFMT_D16_UNORM: return SVGA3D_D16_UNORM;
835 case SVGA3D_DEVCAP_DXFMT_A8_UNORM: return SVGA3D_A8_UNORM;
836 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM: return SVGA3D_BC1_UNORM;
837 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM: return SVGA3D_BC2_UNORM;
838 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM: return SVGA3D_BC3_UNORM;
839 case SVGA3D_DEVCAP_DXFMT_B5G6R5_UNORM: return SVGA3D_B5G6R5_UNORM;
840 case SVGA3D_DEVCAP_DXFMT_B5G5R5A1_UNORM: return SVGA3D_B5G5R5A1_UNORM;
841 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM: return SVGA3D_B8G8R8A8_UNORM;
842 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM: return SVGA3D_B8G8R8X8_UNORM;
843 case SVGA3D_DEVCAP_DXFMT_BC4_UNORM: return SVGA3D_BC4_UNORM;
844 case SVGA3D_DEVCAP_DXFMT_BC5_UNORM: return SVGA3D_BC5_UNORM;
845 case SVGA3D_DEVCAP_DXFMT_BC6H_TYPELESS: return SVGA3D_BC6H_TYPELESS;
846 case SVGA3D_DEVCAP_DXFMT_BC6H_UF16: return SVGA3D_BC6H_UF16;
847 case SVGA3D_DEVCAP_DXFMT_BC6H_SF16: return SVGA3D_BC6H_SF16;
848 case SVGA3D_DEVCAP_DXFMT_BC7_TYPELESS: return SVGA3D_BC7_TYPELESS;
849 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM: return SVGA3D_BC7_UNORM;
850 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM_SRGB: return SVGA3D_BC7_UNORM_SRGB;
851 default:
852 AssertFailed();
853 break;
854 }
855 return SVGA3D_FORMAT_INVALID;
856}
857
858
859static int vmsvgaDXCheckFormatSupportPreDX(PVMSVGA3DSTATE pState, SVGA3dSurfaceFormat enmFormat, uint32_t *pu32DevCap)
860{
861 int rc = VINF_SUCCESS;
862
863 *pu32DevCap = 0;
864
865 DXGI_FORMAT const dxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(enmFormat);
866 if (dxgiFormat != DXGI_FORMAT_UNKNOWN)
867 {
868 RT_NOREF(pState);
869 /** @todo Implement */
870 }
871 else
872 rc = VERR_NOT_SUPPORTED;
873 return rc;
874}
875
876static int vmsvgaDXCheckFormatSupport(PVMSVGA3DSTATE pState, SVGA3dSurfaceFormat enmFormat, uint32_t *pu32DevCap)
877{
878 int rc = VINF_SUCCESS;
879
880 *pu32DevCap = 0;
881
882 DXGI_FORMAT const dxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(enmFormat);
883 if (dxgiFormat != DXGI_FORMAT_UNKNOWN)
884 {
885 ID3D11Device *pDevice = pState->pBackend->dxDevice.pDevice;
886 UINT FormatSupport = 0;
887 HRESULT hr = pDevice->CheckFormatSupport(dxgiFormat, &FormatSupport);
888 if (SUCCEEDED(hr))
889 {
890 *pu32DevCap |= SVGA3D_DXFMT_SUPPORTED;
891
892 if (FormatSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)
893 *pu32DevCap |= SVGA3D_DXFMT_SHADER_SAMPLE;
894
895 if (FormatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)
896 *pu32DevCap |= SVGA3D_DXFMT_COLOR_RENDERTARGET;
897
898 if (FormatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL)
899 *pu32DevCap |= SVGA3D_DXFMT_DEPTH_RENDERTARGET;
900
901 if (FormatSupport & D3D11_FORMAT_SUPPORT_BLENDABLE)
902 *pu32DevCap |= SVGA3D_DXFMT_BLENDABLE;
903
904 if (FormatSupport & D3D11_FORMAT_SUPPORT_MIP)
905 *pu32DevCap |= SVGA3D_DXFMT_MIPS;
906
907 if (FormatSupport & D3D11_FORMAT_SUPPORT_TEXTURECUBE)
908 *pu32DevCap |= SVGA3D_DXFMT_ARRAY;
909
910 if (FormatSupport & D3D11_FORMAT_SUPPORT_TEXTURE3D)
911 *pu32DevCap |= SVGA3D_DXFMT_VOLUME;
912
913 if (FormatSupport & D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER)
914 *pu32DevCap |= SVGA3D_DXFMT_DX_VERTEX_BUFFER;
915
916 if (pState->pBackend->dxDevice.MultisampleCountMask != 0)
917 {
918 UINT NumQualityLevels;
919 hr = pDevice->CheckMultisampleQualityLevels(dxgiFormat, 2, &NumQualityLevels);
920 if (SUCCEEDED(hr) && NumQualityLevels != 0)
921 *pu32DevCap |= SVGA3D_DXFMT_MULTISAMPLE;
922 }
923 }
924 else
925 {
926 LogFunc(("CheckFormatSupport failed for 0x%08x, hr = 0x%08x\n", dxgiFormat, hr));
927 rc = VERR_NOT_SUPPORTED;
928 }
929 }
930 else
931 rc = VERR_NOT_SUPPORTED;
932 return rc;
933}
934
935
936static void dxLogRelVideoCaps(ID3D11VideoDevice *pVideoDevice)
937{
938#define FORMAT_ELEMENT(aFormat) { aFormat, #aFormat }
939 static const struct {
940 DXGI_FORMAT format;
941 char const *pszFormat;
942 } aVDFormats[] =
943 {
944 FORMAT_ELEMENT(DXGI_FORMAT_NV12),
945 FORMAT_ELEMENT(DXGI_FORMAT_YUY2),
946 FORMAT_ELEMENT(DXGI_FORMAT_AYUV),
947 };
948
949 static const struct {
950 DXGI_FORMAT format;
951 char const *pszFormat;
952 } aVPFormats[] =
953 {
954 // Queried from driver
955 FORMAT_ELEMENT(DXGI_FORMAT_R8_UNORM),
956 FORMAT_ELEMENT(DXGI_FORMAT_R16_UNORM),
957 FORMAT_ELEMENT(DXGI_FORMAT_NV12),
958 FORMAT_ELEMENT(DXGI_FORMAT_420_OPAQUE),
959 FORMAT_ELEMENT(DXGI_FORMAT_P010),
960 FORMAT_ELEMENT(DXGI_FORMAT_P016),
961 FORMAT_ELEMENT(DXGI_FORMAT_YUY2),
962 FORMAT_ELEMENT(DXGI_FORMAT_NV11),
963 FORMAT_ELEMENT(DXGI_FORMAT_AYUV),
964 FORMAT_ELEMENT(DXGI_FORMAT_R16G16B16A16_FLOAT),
965 FORMAT_ELEMENT(DXGI_FORMAT_Y216),
966 FORMAT_ELEMENT(DXGI_FORMAT_B8G8R8X8_UNORM),
967 FORMAT_ELEMENT(DXGI_FORMAT_B8G8R8A8_UNORM),
968 FORMAT_ELEMENT(DXGI_FORMAT_R8G8B8A8_UNORM),
969 FORMAT_ELEMENT(DXGI_FORMAT_R10G10B10A2_UNORM),
970
971 // From format table
972 FORMAT_ELEMENT(DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM),
973 FORMAT_ELEMENT(DXGI_FORMAT_R8G8B8A8_UNORM_SRGB),
974 FORMAT_ELEMENT(DXGI_FORMAT_B8G8R8A8_UNORM_SRGB),
975 FORMAT_ELEMENT(DXGI_FORMAT_Y410),
976 FORMAT_ELEMENT(DXGI_FORMAT_Y416),
977 FORMAT_ELEMENT(DXGI_FORMAT_Y210),
978 FORMAT_ELEMENT(DXGI_FORMAT_AI44),
979 FORMAT_ELEMENT(DXGI_FORMAT_IA44),
980 FORMAT_ELEMENT(DXGI_FORMAT_P8),
981 FORMAT_ELEMENT(DXGI_FORMAT_A8P8),
982 };
983#undef FORMAT_ELEMENT
984
985 static char const *apszFilterName[] =
986 {
987 "BRIGHTNESS",
988 "CONTRAST",
989 "HUE",
990 "SATURATION",
991 "NOISE_REDUCTION",
992 "EDGE_ENHANCEMENT",
993 "ANAMORPHIC_SCALING",
994 "STEREO_ADJUSTMENT",
995 };
996
997 HRESULT hr;
998
999 UINT cProfiles = pVideoDevice->GetVideoDecoderProfileCount();
1000 for (UINT i = 0; i < cProfiles; ++i)
1001 {
1002 GUID DecodeProfile;
1003 hr = pVideoDevice->GetVideoDecoderProfile(i, &DecodeProfile);
1004 if (SUCCEEDED(hr))
1005 LogRel(("VMSVGA: DecodeProfile[%d]: %RTuuid\n", i, &DecodeProfile));
1006 }
1007
1008 D3D11_VIDEO_DECODER_DESC DecoderDesc;
1009 // Commonly used D3D11_DECODER_PROFILE_H264_VLD_NOFGT
1010 DecoderDesc.Guid = { 0x1b81be68, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5 };
1011 DecoderDesc.SampleWidth = 1920;
1012 DecoderDesc.SampleHeight = 1080;
1013 DecoderDesc.OutputFormat = DXGI_FORMAT_NV12;
1014
1015 UINT cConfigs = 0;
1016 hr = pVideoDevice->GetVideoDecoderConfigCount(&DecoderDesc, &cConfigs);
1017 for (UINT i = 0; i < cConfigs; ++i)
1018 {
1019 D3D11_VIDEO_DECODER_CONFIG DecoderConfig;
1020 hr = pVideoDevice->GetVideoDecoderConfig(&DecoderDesc, i, &DecoderConfig);
1021 if (SUCCEEDED(hr))
1022 {
1023 LogRel2(("VMSVGA: Config[%d]:\n"
1024 "VMSVGA: %RTuuid\n"
1025 "VMSVGA: %RTuuid\n"
1026 "VMSVGA: %RTuuid\n"
1027 "VMSVGA: BitstreamRaw 0x%x\n"
1028 "VMSVGA: MBCRO 0x%x\n"
1029 "VMSVGA: RDH 0x%x\n"
1030 "VMSVGA: SR8 0x%x\n"
1031 "VMSVGA: R8Sub 0x%x\n"
1032 "VMSVGA: SH8or9C 0x%x\n"
1033 "VMSVGA: SRInterlea 0x%x\n"
1034 "VMSVGA: IRUnsigned 0x%x\n"
1035 "VMSVGA: RDAccel 0x%x\n"
1036 "VMSVGA: HInvScan 0x%x\n"
1037 "VMSVGA: SpecIDCT 0x%x\n"
1038 "VMSVGA: 4GCoefs 0x%x\n"
1039 "VMSVGA: MinRTBC 0x%x\n"
1040 "VMSVGA: DecSpec 0x%x\n"
1041 ,
1042 i, &DecoderConfig.guidConfigBitstreamEncryption,
1043 &DecoderConfig.guidConfigMBcontrolEncryption,
1044 &DecoderConfig.guidConfigResidDiffEncryption,
1045 DecoderConfig.ConfigBitstreamRaw,
1046 DecoderConfig.ConfigMBcontrolRasterOrder,
1047 DecoderConfig.ConfigResidDiffHost,
1048 DecoderConfig.ConfigSpatialResid8,
1049 DecoderConfig.ConfigResid8Subtraction,
1050 DecoderConfig.ConfigSpatialHost8or9Clipping,
1051 DecoderConfig.ConfigSpatialResidInterleaved,
1052 DecoderConfig.ConfigIntraResidUnsigned,
1053 DecoderConfig.ConfigResidDiffAccelerator,
1054 DecoderConfig.ConfigHostInverseScan,
1055 DecoderConfig.ConfigSpecificIDCT,
1056 DecoderConfig.Config4GroupedCoefs,
1057 DecoderConfig.ConfigMinRenderTargetBuffCount,
1058 DecoderConfig.ConfigDecoderSpecific
1059 ));
1060 }
1061 }
1062
1063 for (UINT idxFormat = 0; idxFormat < RT_ELEMENTS(aVDFormats); ++idxFormat)
1064 {
1065 BOOL Supported;
1066 hr = pVideoDevice->CheckVideoDecoderFormat(&DecoderDesc.Guid, aVDFormats[idxFormat].format, &Supported);
1067 if (FAILED(hr))
1068 Supported = FALSE;
1069 LogRel(("VMSVGA: %s: %s\n", aVDFormats[idxFormat].pszFormat, Supported ? "supported" : "-"));
1070 }
1071
1072 /* An arbitrary common video content. */
1073 D3D11_VIDEO_PROCESSOR_CONTENT_DESC Desc;
1074 Desc.InputFrameFormat = D3D11_VIDEO_FRAME_FORMAT_PROGRESSIVE;
1075 Desc.InputFrameRate.Numerator = 25;
1076 Desc.InputFrameRate.Denominator = 1;
1077 Desc.InputWidth = 1920;
1078 Desc.InputHeight = 1080;
1079 Desc.OutputFrameRate.Numerator = 30;
1080 Desc.OutputFrameRate.Denominator = 1;
1081 Desc.OutputWidth = 864;
1082 Desc.OutputHeight = 486;
1083 Desc.Usage = D3D11_VIDEO_USAGE_OPTIMAL_QUALITY;
1084
1085 ID3D11VideoProcessorEnumerator *pEnum = 0;
1086 hr = pVideoDevice->CreateVideoProcessorEnumerator(&Desc, &pEnum);
1087 if (SUCCEEDED(hr))
1088 {
1089 for (unsigned i = 0; i < RT_ELEMENTS(aVPFormats); ++i)
1090 {
1091 UINT Flags;
1092 hr = pEnum->CheckVideoProcessorFormat(aVPFormats[i].format, &Flags);
1093 if (FAILED(hr))
1094 Flags = 0;
1095 LogRel(("VMSVGA: %s: flags %x\n", aVPFormats[i].pszFormat, Flags));
1096 }
1097
1098 D3D11_VIDEO_PROCESSOR_CAPS Caps;
1099 hr = pEnum->GetVideoProcessorCaps(&Caps);
1100 if (SUCCEEDED(hr))
1101 {
1102 LogRel(("VMSVGA: VideoProcessorCaps:\n"
1103 "VMSVGA: DeviceCaps %x\n"
1104 "VMSVGA: FeatureCaps %x\n"
1105 "VMSVGA: FilterCaps %x\n"
1106 "VMSVGA: InputFormatCaps %x\n"
1107 "VMSVGA: AutoStreamCaps %x\n"
1108 "VMSVGA: StereoCaps %x\n"
1109 "VMSVGA: RateConversionCapsCount %d\n"
1110 "VMSVGA: MaxInputStreams %d\n"
1111 "VMSVGA: MaxStreamStates %d\n"
1112 "",
1113 Caps.DeviceCaps,
1114 Caps.FeatureCaps,
1115 Caps.FilterCaps,
1116 Caps.InputFormatCaps,
1117 Caps.AutoStreamCaps,
1118 Caps.StereoCaps,
1119 Caps.RateConversionCapsCount,
1120 Caps.MaxInputStreams,
1121 Caps.MaxStreamStates
1122 ));
1123
1124 for (unsigned i = 0; i < RT_ELEMENTS(apszFilterName); ++i)
1125 {
1126 if (Caps.FilterCaps & (1 << i))
1127 {
1128 D3D11_VIDEO_PROCESSOR_FILTER_RANGE Range;
1129 hr = pEnum->GetVideoProcessorFilterRange((D3D11_VIDEO_PROCESSOR_FILTER)i, &Range);
1130 if (SUCCEEDED(hr))
1131 {
1132 LogRel(("VMSVGA: Filter[%s]: Min %d, Max %d, Default %d, Multiplier " FLOAT_FMT_STR "\n",
1133 apszFilterName[i],
1134 Range.Minimum,
1135 Range.Maximum,
1136 Range.Default,
1137 FLOAT_FMT_ARGS(Range.Multiplier)
1138 ));
1139 }
1140 }
1141 }
1142
1143 for (unsigned idxRateCaps = 0; idxRateCaps < Caps.RateConversionCapsCount; ++idxRateCaps)
1144 {
1145 D3D11_VIDEO_PROCESSOR_RATE_CONVERSION_CAPS RateCaps;
1146 hr = pEnum->GetVideoProcessorRateConversionCaps(idxRateCaps, &RateCaps);
1147 if (SUCCEEDED(hr))
1148 {
1149 LogRel(("VMSVGA: RateConversionCaps[%u]:\n"
1150 "VMSVGA: PastFrames %d\n"
1151 "VMSVGA: FutureFrames %d\n"
1152 "VMSVGA: ProcessorCaps %x\n"
1153 "VMSVGA: ITelecineCaps %x\n"
1154 "VMSVGA: CustomRateCount %d\n"
1155 "",
1156 idxRateCaps,
1157 RateCaps.PastFrames,
1158 RateCaps.FutureFrames,
1159 RateCaps.ProcessorCaps,
1160 RateCaps.ITelecineCaps,
1161 RateCaps.CustomRateCount
1162 ));
1163
1164 for (unsigned idxCustomRateCap = 0; idxCustomRateCap < RateCaps.CustomRateCount; ++idxCustomRateCap)
1165 {
1166 D3D11_VIDEO_PROCESSOR_CUSTOM_RATE Rate;
1167 hr = pEnum->GetVideoProcessorCustomRate(idxRateCaps, idxCustomRateCap, &Rate);
1168 if (SUCCEEDED(hr))
1169 {
1170 LogRel(("VMSVGA: CustomRate[%u][%u]:\n"
1171 "VMSVGA: CustomRate %d/%d\n"
1172 "VMSVGA: OutputFrames %d\n"
1173 "VMSVGA: InputInterlaced %d\n"
1174 "VMSVGA: InputFramesOrFields %d\n"
1175 "",
1176 idxRateCaps, idxCustomRateCap,
1177 Rate.CustomRate.Numerator,
1178 Rate.CustomRate.Denominator,
1179 Rate.OutputFrames,
1180 Rate.InputInterlaced,
1181 Rate.InputFramesOrFields
1182 ));
1183 }
1184 }
1185 }
1186 }
1187 }
1188
1189 D3D_RELEASE(pEnum);
1190 }
1191}
1192
1193
1194static int dxDeviceCreate(PVMSVGA3DBACKEND pBackend, DXDEVICE *pDXDevice)
1195{
1196 int rc = VINF_SUCCESS;
1197
1198 if (pBackend->fSingleDevice && pBackend->dxDevice.pDevice)
1199 {
1200 pDXDevice->pDevice = pBackend->dxDevice.pDevice;
1201 pDXDevice->pDevice->AddRef();
1202
1203 pDXDevice->pImmediateContext = pBackend->dxDevice.pImmediateContext;
1204 pDXDevice->pImmediateContext->AddRef();
1205
1206 pDXDevice->pDxgiFactory = pBackend->dxDevice.pDxgiFactory;
1207 pDXDevice->pDxgiFactory->AddRef();
1208
1209 pDXDevice->FeatureLevel = pBackend->dxDevice.FeatureLevel;
1210
1211 pDXDevice->pVideoDevice = pBackend->dxDevice.pVideoDevice;
1212 if (pDXDevice->pVideoDevice)
1213 pDXDevice->pVideoDevice->AddRef();
1214
1215 pDXDevice->pVideoContext = pBackend->dxDevice.pVideoContext;
1216 if (pDXDevice->pVideoContext)
1217 pDXDevice->pVideoContext->AddRef();
1218
1219#ifdef DX_COMMON_STAGING_BUFFER
1220 pDXDevice->pStagingBuffer = 0;
1221 pDXDevice->cbStagingBuffer = 0;
1222#endif
1223
1224 BlitInit(&pDXDevice->Blitter, pDXDevice->pDevice, pDXDevice->pImmediateContext);
1225 return rc;
1226 }
1227
1228 IDXGIAdapter *pAdapter = NULL; /* Default adapter. */
1229 static D3D_FEATURE_LEVEL const s_aFeatureLevels[] =
1230 {
1231 D3D_FEATURE_LEVEL_11_1,
1232 D3D_FEATURE_LEVEL_11_0
1233 };
1234 UINT Flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
1235#ifdef DEBUG
1236 Flags |= D3D11_CREATE_DEVICE_DEBUG;
1237#endif
1238
1239 ID3D11Device *pDevice = 0;
1240 ID3D11DeviceContext *pImmediateContext = 0;
1241 HRESULT hr = pBackend->pfnD3D11CreateDevice(pAdapter,
1242 D3D_DRIVER_TYPE_HARDWARE,
1243 NULL,
1244 Flags,
1245 s_aFeatureLevels,
1246 RT_ELEMENTS(s_aFeatureLevels),
1247 D3D11_SDK_VERSION,
1248 &pDevice,
1249 &pDXDevice->FeatureLevel,
1250 &pImmediateContext);
1251#ifdef DEBUG
1252 if (FAILED(hr))
1253 {
1254 /* Device creation may fail because _DEBUG flag requires "D3D11 SDK Layers for Windows 10" ("Graphics Tools"):
1255 * Settings/System/Apps/Optional features/Add a feature/Graphics Tools
1256 * Retry without the flag.
1257 */
1258 Flags &= ~D3D11_CREATE_DEVICE_DEBUG;
1259 hr = pBackend->pfnD3D11CreateDevice(pAdapter,
1260 D3D_DRIVER_TYPE_HARDWARE,
1261 NULL,
1262 Flags,
1263 s_aFeatureLevels,
1264 RT_ELEMENTS(s_aFeatureLevels),
1265 D3D11_SDK_VERSION,
1266 &pDevice,
1267 &pDXDevice->FeatureLevel,
1268 &pImmediateContext);
1269 }
1270#endif
1271
1272 if (SUCCEEDED(hr))
1273 {
1274 LogRel(("VMSVGA: Feature level %#x\n", pDXDevice->FeatureLevel));
1275
1276 hr = pDevice->QueryInterface(__uuidof(ID3D11Device1), (void**)&pDXDevice->pDevice);
1277 AssertReturnStmt(SUCCEEDED(hr),
1278 D3D_RELEASE(pImmediateContext); D3D_RELEASE(pDevice),
1279 VERR_NOT_SUPPORTED);
1280
1281 hr = pImmediateContext->QueryInterface(__uuidof(ID3D11DeviceContext1), (void**)&pDXDevice->pImmediateContext);
1282 AssertReturnStmt(SUCCEEDED(hr),
1283 D3D_RELEASE(pImmediateContext); D3D_RELEASE(pDXDevice->pDevice); D3D_RELEASE(pDevice),
1284 VERR_NOT_SUPPORTED);
1285
1286 HRESULT hr2;
1287#ifdef DEBUG
1288 /* Break into debugger when DX runtime detects anything unusual. */
1289 ID3D11Debug *pDebug = 0;
1290 hr2 = pDXDevice->pDevice->QueryInterface(__uuidof(ID3D11Debug), (void**)&pDebug);
1291 if (SUCCEEDED(hr2))
1292 {
1293 ID3D11InfoQueue *pInfoQueue = 0;
1294 hr2 = pDebug->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&pInfoQueue);
1295 if (SUCCEEDED(hr2))
1296 {
1297 pInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
1298// pInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
1299// pInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, true);
1300
1301 /* No breakpoints for the following messages. */
1302 D3D11_MESSAGE_ID saIgnoredMessageIds[] =
1303 {
1304 /* Message ID: Caused by: */
1305 D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_TYPE_MISMATCH, /* Autogenerated input signatures. */
1306 D3D11_MESSAGE_ID_LIVE_DEVICE, /* Live object report. Does not seem to prevent a breakpoint. */
1307 (D3D11_MESSAGE_ID)3146081 /*DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET*/, /* U. */
1308 D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_NOT_SET, /* U. */
1309 D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_MISMATCH, /* U. */
1310 D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_EMPTY_LAYOUT, /* P. */
1311 D3D11_MESSAGE_ID_DEVICE_SHADER_LINKAGE_REGISTERMASK, /* S. */
1312 };
1313
1314 D3D11_INFO_QUEUE_FILTER filter;
1315 RT_ZERO(filter);
1316 filter.DenyList.NumIDs = RT_ELEMENTS(saIgnoredMessageIds);
1317 filter.DenyList.pIDList = saIgnoredMessageIds;
1318 pInfoQueue->AddStorageFilterEntries(&filter);
1319
1320 D3D_RELEASE(pInfoQueue);
1321 }
1322 D3D_RELEASE(pDebug);
1323 }
1324#endif
1325
1326 IDXGIDevice *pDxgiDevice = 0;
1327 hr = pDXDevice->pDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&pDxgiDevice);
1328 if (SUCCEEDED(hr))
1329 {
1330 IDXGIAdapter *pDxgiAdapter = 0;
1331 hr = pDxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&pDxgiAdapter);
1332 if (SUCCEEDED(hr))
1333 {
1334 hr = pDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&pDXDevice->pDxgiFactory);
1335 D3D_RELEASE(pDxgiAdapter);
1336 }
1337
1338 D3D_RELEASE(pDxgiDevice);
1339 }
1340
1341 /* Failure to query VideoDevice should be ignored. */
1342 hr2 = pDXDevice->pDevice->QueryInterface(__uuidof(ID3D11VideoDevice), (void**)&pDXDevice->pVideoDevice);
1343 Assert(SUCCEEDED(hr2));
1344 if (SUCCEEDED(hr2))
1345 {
1346 hr2 = pDXDevice->pImmediateContext->QueryInterface(__uuidof(ID3D11VideoContext), (void**)&pDXDevice->pVideoContext);
1347 Assert(SUCCEEDED(hr2));
1348 if (SUCCEEDED(hr2))
1349 {
1350 LogRel(("VMSVGA: VideoDevice available\n"));
1351 }
1352 else
1353 {
1354 D3D_RELEASE(pDXDevice->pVideoDevice);
1355 pDXDevice->pVideoContext = NULL;
1356 }
1357 }
1358 else
1359 pDXDevice->pVideoDevice = NULL;
1360 }
1361
1362 if (SUCCEEDED(hr))
1363 BlitInit(&pDXDevice->Blitter, pDXDevice->pDevice, pDXDevice->pImmediateContext);
1364 else
1365 rc = VERR_NOT_SUPPORTED;
1366
1367 if (SUCCEEDED(hr))
1368 {
1369 /* Query multisample support for a common format. */
1370 DXGI_FORMAT const dxgiFormat = DXGI_FORMAT_B8G8R8A8_UNORM;
1371
1372 for (uint32_t i = 2; i <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i *= 2)
1373 {
1374 UINT NumQualityLevels = 0;
1375 HRESULT hr2 = pDXDevice->pDevice->CheckMultisampleQualityLevels(dxgiFormat, i, &NumQualityLevels);
1376 if (SUCCEEDED(hr2) && NumQualityLevels > 0)
1377 pDXDevice->MultisampleCountMask |= UINT32_C(1) << (i - 1);
1378 }
1379 }
1380 return rc;
1381}
1382
1383
1384static void dxDeviceDestroy(PVMSVGA3DBACKEND pBackend, DXDEVICE *pDevice)
1385{
1386 RT_NOREF(pBackend);
1387
1388 BlitRelease(&pDevice->Blitter);
1389
1390#ifdef DX_COMMON_STAGING_BUFFER
1391 D3D_RELEASE(pDevice->pStagingBuffer);
1392#endif
1393
1394 D3D_RELEASE(pDevice->pVideoDevice);
1395 D3D_RELEASE(pDevice->pVideoContext);
1396
1397 D3D_RELEASE(pDevice->pDxgiFactory);
1398 D3D_RELEASE(pDevice->pImmediateContext);
1399
1400#ifdef DEBUG
1401 HRESULT hr2;
1402 ID3D11Debug *pDebug = 0;
1403 hr2 = pDevice->pDevice->QueryInterface(__uuidof(ID3D11Debug), (void**)&pDebug);
1404 if (SUCCEEDED(hr2))
1405 {
1406 /// @todo Use this to see whether all resources have been properly released.
1407 //DEBUG_BREAKPOINT_TEST();
1408 //pDebug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL | (D3D11_RLDO_FLAGS)0x4 /*D3D11_RLDO_IGNORE_INTERNAL*/);
1409 D3D_RELEASE(pDebug);
1410 }
1411#endif
1412
1413 D3D_RELEASE(pDevice->pDevice);
1414 RT_ZERO(*pDevice);
1415}
1416
1417
1418static void dxViewAddToList(PVGASTATECC pThisCC, DXVIEW *pDXView)
1419{
1420 LogFunc(("cid = %u, sid = %u, viewId = %u, type = %u\n",
1421 pDXView->cid, pDXView->sid, pDXView->viewId, pDXView->enmViewType));
1422
1423 Assert(pDXView->u.pView); /* Only already created views should be added. Guard against mis-use by callers. */
1424
1425 PVMSVGA3DSURFACE pSurface;
1426 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pDXView->sid, &pSurface);
1427 AssertRCReturnVoid(rc);
1428
1429 RTListAppend(&pSurface->pBackendSurface->listView, &pDXView->nodeSurfaceView);
1430}
1431
1432
1433static void dxViewRemoveFromList(DXVIEW *pDXView)
1434{
1435 LogFunc(("cid = %u, sid = %u, viewId = %u, type = %u\n",
1436 pDXView->cid, pDXView->sid, pDXView->viewId, pDXView->enmViewType));
1437 /* pView can be NULL, if COT entry is already empty. */
1438 if (pDXView->u.pView)
1439 {
1440 Assert(pDXView->nodeSurfaceView.pNext && pDXView->nodeSurfaceView.pPrev);
1441 RTListNodeRemove(&pDXView->nodeSurfaceView);
1442 }
1443}
1444
1445
1446static int dxViewDestroy(DXVIEW *pDXView)
1447{
1448 LogFunc(("cid = %u, sid = %u, viewId = %u, type = %u\n",
1449 pDXView->cid, pDXView->sid, pDXView->viewId, pDXView->enmViewType));
1450 if (pDXView->u.pView)
1451 {
1452 D3D_RELEASE(pDXView->u.pView);
1453 RTListNodeRemove(&pDXView->nodeSurfaceView);
1454 RT_ZERO(*pDXView);
1455 }
1456
1457 return VINF_SUCCESS;
1458}
1459
1460
1461static int dxViewInit(DXVIEW *pDXView, PVMSVGA3DSURFACE pSurface, VMSVGA3DDXCONTEXT *pDXContext, uint32_t viewId, VMSVGA3DBACKVIEWTYPE enmViewType, ID3D11View *pView)
1462{
1463 pDXView->cid = pDXContext->cid;
1464 pDXView->sid = pSurface->id;
1465 pDXView->viewId = viewId;
1466 pDXView->enmViewType = enmViewType;
1467 pDXView->u.pView = pView;
1468 RTListAppend(&pSurface->pBackendSurface->listView, &pDXView->nodeSurfaceView);
1469
1470 LogFunc(("cid = %u, sid = %u, viewId = %u, type = %u\n",
1471 pDXView->cid, pDXView->sid, pDXView->viewId, pDXView->enmViewType));
1472
1473DXVIEW *pIter, *pNext;
1474RTListForEachSafe(&pSurface->pBackendSurface->listView, pIter, pNext, DXVIEW, nodeSurfaceView)
1475{
1476 AssertPtr(pNext);
1477 LogFunc(("pIter=%p, pNext=%p\n", pIter, pNext));
1478}
1479
1480 return VINF_SUCCESS;
1481}
1482
1483
1484DECLINLINE(bool) dxIsSurfaceShareable(PVMSVGA3DSURFACE pSurface)
1485{
1486 /* It is not expected that volume textures will be shared between contexts. */
1487 if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_VOLUME)
1488 return false;
1489
1490 return (pSurface->f.surfaceFlags & SVGA3D_SURFACE_SCREENTARGET)
1491 || (pSurface->f.surfaceFlags & SVGA3D_SURFACE_BIND_RENDER_TARGET);
1492}
1493
1494
1495static DXDEVICE *dxDeviceFromCid(uint32_t cid, PVMSVGA3DSTATE pState)
1496{
1497 if (cid != DX_CID_BACKEND)
1498 {
1499 if (pState->pBackend->fSingleDevice)
1500 return &pState->pBackend->dxDevice;
1501
1502 VMSVGA3DDXCONTEXT *pDXContext;
1503 int rc = vmsvga3dDXContextFromCid(pState, cid, &pDXContext);
1504 if (RT_SUCCESS(rc))
1505 return &pDXContext->pBackendDXContext->dxDevice;
1506 }
1507 else
1508 return &pState->pBackend->dxDevice;
1509
1510 AssertFailed();
1511 return NULL;
1512}
1513
1514
1515static DXDEVICE *dxDeviceFromContext(PVMSVGA3DSTATE p3dState, VMSVGA3DDXCONTEXT *pDXContext)
1516{
1517 DXDEVICE *pDXDevice;
1518 if (pDXContext && !p3dState->pBackend->fSingleDevice)
1519 pDXDevice = &pDXContext->pBackendDXContext->dxDevice;
1520 else
1521 pDXDevice = &p3dState->pBackend->dxDevice;
1522
1523#ifdef DEBUG
1524 HRESULT hr = pDXDevice->pDevice->GetDeviceRemovedReason();
1525 Assert(SUCCEEDED(hr));
1526#endif
1527 return pDXDevice;
1528}
1529
1530
1531static int dxDeviceFlush(DXDEVICE *pDevice)
1532{
1533 /** @todo Should the flush follow the query submission? */
1534 pDevice->pImmediateContext->Flush();
1535
1536 ID3D11Query *pQuery = 0;
1537 D3D11_QUERY_DESC qd;
1538 RT_ZERO(qd);
1539 qd.Query = D3D11_QUERY_EVENT;
1540
1541 HRESULT hr = pDevice->pDevice->CreateQuery(&qd, &pQuery);
1542 Assert(hr == S_OK); RT_NOREF(hr);
1543 pDevice->pImmediateContext->End(pQuery);
1544
1545 BOOL queryData;
1546 while (pDevice->pImmediateContext->GetData(pQuery, &queryData, sizeof(queryData), 0) != S_OK)
1547 RTThreadYield();
1548
1549 D3D_RELEASE(pQuery);
1550
1551 return VINF_SUCCESS;
1552}
1553
1554
1555static int dxContextWait(uint32_t cidDrawing, PVMSVGA3DSTATE pState)
1556{
1557 if (pState->pBackend->fSingleDevice)
1558 return VINF_SUCCESS;
1559
1560 /* Flush cidDrawing context and issue a query. */
1561 DXDEVICE *pDXDevice = dxDeviceFromCid(cidDrawing, pState);
1562 if (pDXDevice)
1563 return dxDeviceFlush(pDXDevice);
1564 /* cidDrawing does not exist anymore. */
1565 return VINF_SUCCESS;
1566}
1567
1568
1569static int dxSurfaceWait(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface, uint32_t cidRequesting)
1570{
1571 if (pState->pBackend->fSingleDevice)
1572 return VINF_SUCCESS;
1573
1574 VMSVGA3DBACKENDSURFACE *pBackendSurface = pSurface->pBackendSurface;
1575 if (!pBackendSurface)
1576 AssertFailedReturn(VERR_INVALID_STATE);
1577
1578 int rc = VINF_SUCCESS;
1579 if (pBackendSurface->cidDrawing != SVGA_ID_INVALID)
1580 {
1581 if (pBackendSurface->cidDrawing != cidRequesting)
1582 {
1583 LogFunc(("sid = %u, assoc cid = %u, drawing cid = %u, req cid = %u\n",
1584 pSurface->id, pSurface->idAssociatedContext, pBackendSurface->cidDrawing, cidRequesting));
1585 Assert(dxIsSurfaceShareable(pSurface));
1586 rc = dxContextWait(pBackendSurface->cidDrawing, pState);
1587 pBackendSurface->cidDrawing = SVGA_ID_INVALID;
1588 }
1589 }
1590 return rc;
1591}
1592
1593
1594static ID3D11Resource *dxResource(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface, VMSVGA3DDXCONTEXT *pDXContext)
1595{
1596 VMSVGA3DBACKENDSURFACE *pBackendSurface = pSurface->pBackendSurface;
1597 if (!pBackendSurface)
1598 AssertFailedReturn(NULL);
1599
1600 ID3D11Resource *pResource;
1601
1602 uint32_t const cidRequesting = pDXContext ? pDXContext->cid : DX_CID_BACKEND;
1603 if (cidRequesting == pSurface->idAssociatedContext || pState->pBackend->fSingleDevice)
1604 pResource = pBackendSurface->u.pResource;
1605 else
1606 {
1607 /*
1608 * Context, which as not created the surface, is requesting.
1609 */
1610 AssertReturn(pDXContext, NULL);
1611
1612 Assert(dxIsSurfaceShareable(pSurface));
1613 Assert(pSurface->idAssociatedContext == DX_CID_BACKEND);
1614
1615 DXSHAREDTEXTURE *pSharedTexture = (DXSHAREDTEXTURE *)RTAvlU32Get(&pBackendSurface->SharedTextureTree, pDXContext->cid);
1616 if (!pSharedTexture)
1617 {
1618 DXDEVICE *pDevice = dxDeviceFromContext(pState, pDXContext);
1619 AssertReturn(pDevice->pDevice, NULL);
1620
1621 AssertReturn(pBackendSurface->SharedHandle, NULL);
1622
1623 /* This context has not yet opened the texture. */
1624 pSharedTexture = (DXSHAREDTEXTURE *)RTMemAllocZ(sizeof(DXSHAREDTEXTURE));
1625 AssertReturn(pSharedTexture, NULL);
1626
1627 pSharedTexture->Core.Key = pDXContext->cid;
1628 bool const fSuccess = RTAvlU32Insert(&pBackendSurface->SharedTextureTree, &pSharedTexture->Core);
1629 AssertReturn(fSuccess, NULL);
1630
1631 HRESULT hr = pDevice->pDevice->OpenSharedResource(pBackendSurface->SharedHandle, __uuidof(ID3D11Texture2D), (void**)&pSharedTexture->pTexture);
1632 Assert(SUCCEEDED(hr));
1633 if (SUCCEEDED(hr))
1634 pSharedTexture->sid = pSurface->id;
1635 else
1636 {
1637 RTAvlU32Remove(&pBackendSurface->SharedTextureTree, pDXContext->cid);
1638 RTMemFree(pSharedTexture);
1639 return NULL;
1640 }
1641 }
1642
1643 pResource = pSharedTexture->pTexture;
1644 }
1645
1646 /* Wait for drawing to finish. */
1647 dxSurfaceWait(pState, pSurface, cidRequesting);
1648
1649 return pResource;
1650}
1651
1652
1653static uint32_t dxGetRenderTargetViewSid(PVMSVGA3DDXCONTEXT pDXContext, uint32_t renderTargetViewId)
1654{
1655 ASSERT_GUEST_RETURN(renderTargetViewId < pDXContext->cot.cRTView, SVGA_ID_INVALID);
1656
1657 SVGACOTableDXRTViewEntry const *pRTViewEntry = &pDXContext->cot.paRTView[renderTargetViewId];
1658 return pRTViewEntry->sid;
1659}
1660
1661
1662static int dxTrackRenderTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
1663{
1664 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1665 AssertReturn(pState, VERR_INVALID_STATE);
1666
1667 for (unsigned long i = 0; i < RT_ELEMENTS(pDXContext->svgaDXContext.renderState.renderTargetViewIds); ++i)
1668 {
1669 uint32_t const renderTargetViewId = pDXContext->svgaDXContext.renderState.renderTargetViewIds[i];
1670 if (renderTargetViewId == SVGA_ID_INVALID)
1671 continue;
1672
1673 uint32_t const sid = dxGetRenderTargetViewSid(pDXContext, renderTargetViewId);
1674 LogFunc(("[%u] sid = %u, drawing cid = %u\n", i, sid, pDXContext->cid));
1675
1676 PVMSVGA3DSURFACE pSurface;
1677 int rc = vmsvga3dSurfaceFromSid(pState, sid, &pSurface);
1678 if (RT_SUCCESS(rc))
1679 {
1680 AssertContinue(pSurface->pBackendSurface);
1681 pSurface->pBackendSurface->cidDrawing = pDXContext->cid;
1682 }
1683 }
1684 return VINF_SUCCESS;
1685}
1686
1687
1688static int dxDefineStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid, SVGACOTableDXStreamOutputEntry const *pEntry, DXSHADER *pDXShader)
1689{
1690 PVMSVGAR3STATE const pSvgaR3State = pThisCC->svga.pSvgaR3State;
1691 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
1692
1693 /* Make D3D11_SO_DECLARATION_ENTRY array from SVGA3dStreamOutputDeclarationEntry. */
1694 SVGA3dStreamOutputDeclarationEntry const *paDecls;
1695 PVMSVGAMOB pMob = NULL;
1696 if (pEntry->usesMob)
1697 {
1698 pMob = vmsvgaR3MobGet(pSvgaR3State, pEntry->mobid);
1699 ASSERT_GUEST_RETURN(pMob, VERR_INVALID_PARAMETER);
1700
1701 /* Create a memory pointer for the MOB, which is accessible by host. */
1702 int rc = vmsvgaR3MobBackingStoreCreate(pSvgaR3State, pMob, vmsvgaR3MobSize(pMob));
1703 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
1704
1705 /* Get pointer to the shader bytecode. This will also verify the offset. */
1706 paDecls = (SVGA3dStreamOutputDeclarationEntry const *)vmsvgaR3MobBackingStorePtr(pMob, pEntry->offsetInBytes);
1707 AssertReturnStmt(paDecls, vmsvgaR3MobBackingStoreDelete(pSvgaR3State, pMob), VERR_INTERNAL_ERROR);
1708 }
1709 else
1710 paDecls = &pEntry->decl[0];
1711
1712 pDXStreamOutput->cDeclarationEntry = pEntry->numOutputStreamEntries;
1713 for (uint32_t i = 0; i < pDXStreamOutput->cDeclarationEntry; ++i)
1714 {
1715 D3D11_SO_DECLARATION_ENTRY *pDst = &pDXStreamOutput->aDeclarationEntry[i];
1716 SVGA3dStreamOutputDeclarationEntry const *pSrc = &paDecls[i];
1717
1718 uint32_t const registerMask = pSrc->registerMask & 0xF;
1719 unsigned const iFirstBit = ASMBitFirstSetU32(registerMask);
1720 unsigned const iLastBit = ASMBitLastSetU32(registerMask);
1721
1722 pDst->Stream = pSrc->stream;
1723 pDst->SemanticName = NULL; /* Semantic name and index will be taken from the shader output declaration. */
1724 pDst->SemanticIndex = 0;
1725 pDst->StartComponent = iFirstBit > 0 ? iFirstBit - 1 : 0;
1726 pDst->ComponentCount = iFirstBit > 0 ? iLastBit - (iFirstBit - 1) : 0;
1727 pDst->OutputSlot = pSrc->outputSlot;
1728 }
1729
1730 uint32_t MaxSemanticIndex = 0;
1731 for (uint32_t i = 0; i < pDXStreamOutput->cDeclarationEntry; ++i)
1732 {
1733 D3D11_SO_DECLARATION_ENTRY *pDeclarationEntry = &pDXStreamOutput->aDeclarationEntry[i];
1734 SVGA3dStreamOutputDeclarationEntry const *decl = &paDecls[i];
1735
1736 /* Find the corresponding register and mask in the GS shader output. */
1737 int idxFound = -1;
1738 for (uint32_t iOutputEntry = 0; iOutputEntry < pDXShader->shaderInfo.cOutputSignature; ++iOutputEntry)
1739 {
1740 SVGA3dDXSignatureEntry const *pOutputEntry = &pDXShader->shaderInfo.aOutputSignature[iOutputEntry];
1741 if ( pOutputEntry->registerIndex == decl->registerIndex
1742 && (decl->registerMask & ~pOutputEntry->mask) == 0) /* SO decl mask is a subset of shader output mask. */
1743 {
1744 idxFound = iOutputEntry;
1745 break;
1746 }
1747 }
1748
1749 if (idxFound >= 0)
1750 {
1751 DXShaderAttributeSemantic const *pOutputSemantic = &pDXShader->shaderInfo.aOutputSemantic[idxFound];
1752 pDeclarationEntry->SemanticName = pOutputSemantic->pcszSemanticName;
1753 pDeclarationEntry->SemanticIndex = pOutputSemantic->SemanticIndex;
1754 MaxSemanticIndex = RT_MAX(MaxSemanticIndex, pOutputSemantic->SemanticIndex);
1755 }
1756 else
1757 AssertFailed();
1758 }
1759
1760 /* A geometry shader may return components of the same register as different attributes:
1761 *
1762 * Output signature
1763 * Name Index Mask Register
1764 * ATTRIB 2 xy 2
1765 * ATTRIB 3 z 2
1766 *
1767 * For ATTRIB 3 the stream output declaration expects StartComponent = 0 and ComponentCount = 1
1768 * (not StartComponent = 2 and ComponentCount = 1):
1769 *
1770 * Stream output declaration
1771 * SemanticName SemanticIndex StartComponent ComponentCount
1772 * ATTRIB 2 0 2
1773 * ATTRIB 3 0 1
1774 *
1775 * Stream output declaration can have multiple entries for the same attribute.
1776 * In this case StartComponent is the offset within the attribute.
1777 *
1778 * Output signature
1779 * Name Index Mask Register
1780 * ATTRIB 0 xyzw 0
1781 *
1782 * Stream output declaration
1783 * SemanticName SemanticIndex StartComponent ComponentCount
1784 * ATTRIB 0 0 1
1785 * ATTRIB 0 1 1
1786 *
1787 * StartComponent has been computed as the component offset in a register:
1788 * 'StartComponent = iFirstBit > 0 ? iFirstBit - 1 : 0;'.
1789 *
1790 * StartComponent must be the offset in an attribute.
1791 */
1792 for (uint32_t SemanticIndex = 0; SemanticIndex <= MaxSemanticIndex; ++SemanticIndex)
1793 {
1794 /* Find minimum StartComponent value for this attribute. */
1795 uint32_t MinStartComponent = UINT32_MAX;
1796 for (uint32_t i = 0; i < pDXStreamOutput->cDeclarationEntry; ++i)
1797 {
1798 D3D11_SO_DECLARATION_ENTRY *pDeclarationEntry = &pDXStreamOutput->aDeclarationEntry[i];
1799 if (pDeclarationEntry->SemanticIndex == SemanticIndex)
1800 MinStartComponent = RT_MIN(MinStartComponent, pDeclarationEntry->StartComponent);
1801 }
1802
1803 AssertContinue(MinStartComponent != UINT32_MAX);
1804
1805 /* Adjust the StartComponent to start from 0 for this attribute. */
1806 for (uint32_t i = 0; i < pDXStreamOutput->cDeclarationEntry; ++i)
1807 {
1808 D3D11_SO_DECLARATION_ENTRY *pDeclarationEntry = &pDXStreamOutput->aDeclarationEntry[i];
1809 if (pDeclarationEntry->SemanticIndex == SemanticIndex)
1810 pDeclarationEntry->StartComponent -= MinStartComponent;
1811 }
1812 }
1813
1814 if (pMob)
1815 vmsvgaR3MobBackingStoreDelete(pSvgaR3State, pMob);
1816
1817 return VINF_SUCCESS;
1818}
1819
1820static void dxDestroyStreamOutput(DXSTREAMOUTPUT *pDXStreamOutput)
1821{
1822 RT_ZERO(*pDXStreamOutput);
1823}
1824
1825static D3D11_BLEND dxBlendFactorAlpha(uint8_t svgaBlend)
1826{
1827 /* "Blend options that end in _COLOR are not allowed." but the guest sometimes sends them. */
1828 switch (svgaBlend)
1829 {
1830 case SVGA3D_BLENDOP_ZERO: return D3D11_BLEND_ZERO;
1831 case SVGA3D_BLENDOP_ONE: return D3D11_BLEND_ONE;
1832 case SVGA3D_BLENDOP_SRCCOLOR: return D3D11_BLEND_SRC_ALPHA;
1833 case SVGA3D_BLENDOP_INVSRCCOLOR: return D3D11_BLEND_INV_SRC_ALPHA;
1834 case SVGA3D_BLENDOP_SRCALPHA: return D3D11_BLEND_SRC_ALPHA;
1835 case SVGA3D_BLENDOP_INVSRCALPHA: return D3D11_BLEND_INV_SRC_ALPHA;
1836 case SVGA3D_BLENDOP_DESTALPHA: return D3D11_BLEND_DEST_ALPHA;
1837 case SVGA3D_BLENDOP_INVDESTALPHA: return D3D11_BLEND_INV_DEST_ALPHA;
1838 case SVGA3D_BLENDOP_DESTCOLOR: return D3D11_BLEND_DEST_ALPHA;
1839 case SVGA3D_BLENDOP_INVDESTCOLOR: return D3D11_BLEND_INV_DEST_ALPHA;
1840 case SVGA3D_BLENDOP_SRCALPHASAT: return D3D11_BLEND_SRC_ALPHA_SAT;
1841 case SVGA3D_BLENDOP_BLENDFACTOR: return D3D11_BLEND_BLEND_FACTOR;
1842 case SVGA3D_BLENDOP_INVBLENDFACTOR: return D3D11_BLEND_INV_BLEND_FACTOR;
1843 case SVGA3D_BLENDOP_SRC1COLOR: return D3D11_BLEND_SRC1_ALPHA;
1844 case SVGA3D_BLENDOP_INVSRC1COLOR: return D3D11_BLEND_INV_SRC1_ALPHA;
1845 case SVGA3D_BLENDOP_SRC1ALPHA: return D3D11_BLEND_SRC1_ALPHA;
1846 case SVGA3D_BLENDOP_INVSRC1ALPHA: return D3D11_BLEND_INV_SRC1_ALPHA;
1847 case SVGA3D_BLENDOP_BLENDFACTORALPHA: return D3D11_BLEND_BLEND_FACTOR;
1848 case SVGA3D_BLENDOP_INVBLENDFACTORALPHA: return D3D11_BLEND_INV_BLEND_FACTOR;
1849 default:
1850 break;
1851 }
1852 return D3D11_BLEND_ZERO;
1853}
1854
1855
1856static D3D11_BLEND dxBlendFactorColor(uint8_t svgaBlend)
1857{
1858 switch (svgaBlend)
1859 {
1860 case SVGA3D_BLENDOP_ZERO: return D3D11_BLEND_ZERO;
1861 case SVGA3D_BLENDOP_ONE: return D3D11_BLEND_ONE;
1862 case SVGA3D_BLENDOP_SRCCOLOR: return D3D11_BLEND_SRC_COLOR;
1863 case SVGA3D_BLENDOP_INVSRCCOLOR: return D3D11_BLEND_INV_SRC_COLOR;
1864 case SVGA3D_BLENDOP_SRCALPHA: return D3D11_BLEND_SRC_ALPHA;
1865 case SVGA3D_BLENDOP_INVSRCALPHA: return D3D11_BLEND_INV_SRC_ALPHA;
1866 case SVGA3D_BLENDOP_DESTALPHA: return D3D11_BLEND_DEST_ALPHA;
1867 case SVGA3D_BLENDOP_INVDESTALPHA: return D3D11_BLEND_INV_DEST_ALPHA;
1868 case SVGA3D_BLENDOP_DESTCOLOR: return D3D11_BLEND_DEST_COLOR;
1869 case SVGA3D_BLENDOP_INVDESTCOLOR: return D3D11_BLEND_INV_DEST_COLOR;
1870 case SVGA3D_BLENDOP_SRCALPHASAT: return D3D11_BLEND_SRC_ALPHA_SAT;
1871 case SVGA3D_BLENDOP_BLENDFACTOR: return D3D11_BLEND_BLEND_FACTOR;
1872 case SVGA3D_BLENDOP_INVBLENDFACTOR: return D3D11_BLEND_INV_BLEND_FACTOR;
1873 case SVGA3D_BLENDOP_SRC1COLOR: return D3D11_BLEND_SRC1_COLOR;
1874 case SVGA3D_BLENDOP_INVSRC1COLOR: return D3D11_BLEND_INV_SRC1_COLOR;
1875 case SVGA3D_BLENDOP_SRC1ALPHA: return D3D11_BLEND_SRC1_ALPHA;
1876 case SVGA3D_BLENDOP_INVSRC1ALPHA: return D3D11_BLEND_INV_SRC1_ALPHA;
1877 case SVGA3D_BLENDOP_BLENDFACTORALPHA: return D3D11_BLEND_BLEND_FACTOR;
1878 case SVGA3D_BLENDOP_INVBLENDFACTORALPHA: return D3D11_BLEND_INV_BLEND_FACTOR;
1879 default:
1880 break;
1881 }
1882 return D3D11_BLEND_ZERO;
1883}
1884
1885
1886static D3D11_BLEND_OP dxBlendOp(uint8_t svgaBlendEq)
1887{
1888 return (D3D11_BLEND_OP)svgaBlendEq;
1889}
1890
1891
1892static D3D11_LOGIC_OP dxLogicOp(uint8_t svgaLogicEq)
1893{
1894 return (D3D11_LOGIC_OP)svgaLogicEq;
1895}
1896
1897
1898/** @todo AssertCompile for types like D3D11_COMPARISON_FUNC and SVGA3dComparisonFunc */
1899static HRESULT dxBlendStateCreate(DXDEVICE *pDevice, SVGACOTableDXBlendStateEntry const *pEntry, ID3D11BlendState1 **pp)
1900{
1901 D3D11_BLEND_DESC1 BlendDesc;
1902 BlendDesc.AlphaToCoverageEnable = RT_BOOL(pEntry->alphaToCoverageEnable);
1903 BlendDesc.IndependentBlendEnable = RT_BOOL(pEntry->independentBlendEnable);
1904 for (int i = 0; i < SVGA3D_MAX_RENDER_TARGETS; ++i)
1905 {
1906 BlendDesc.RenderTarget[i].BlendEnable = RT_BOOL(pEntry->perRT[i].blendEnable);
1907 BlendDesc.RenderTarget[i].LogicOpEnable = RT_BOOL(pEntry->perRT[i].logicOpEnable);
1908 BlendDesc.RenderTarget[i].SrcBlend = dxBlendFactorColor(pEntry->perRT[i].srcBlend);
1909 BlendDesc.RenderTarget[i].DestBlend = dxBlendFactorColor(pEntry->perRT[i].destBlend);
1910 BlendDesc.RenderTarget[i].BlendOp = dxBlendOp (pEntry->perRT[i].blendOp);
1911 BlendDesc.RenderTarget[i].SrcBlendAlpha = dxBlendFactorAlpha(pEntry->perRT[i].srcBlendAlpha);
1912 BlendDesc.RenderTarget[i].DestBlendAlpha = dxBlendFactorAlpha(pEntry->perRT[i].destBlendAlpha);
1913 BlendDesc.RenderTarget[i].BlendOpAlpha = dxBlendOp (pEntry->perRT[i].blendOpAlpha);
1914 BlendDesc.RenderTarget[i].LogicOp = dxLogicOp (pEntry->perRT[i].logicOp);
1915 BlendDesc.RenderTarget[i].RenderTargetWriteMask = pEntry->perRT[i].renderTargetWriteMask;
1916 }
1917
1918 HRESULT hr = pDevice->pDevice->CreateBlendState1(&BlendDesc, pp);
1919 Assert(SUCCEEDED(hr));
1920 return hr;
1921}
1922
1923
1924static HRESULT dxDepthStencilStateCreate(DXDEVICE *pDevice, SVGACOTableDXDepthStencilEntry const *pEntry, ID3D11DepthStencilState **pp)
1925{
1926 D3D11_DEPTH_STENCIL_DESC desc;
1927 desc.DepthEnable = pEntry->depthEnable;
1928 desc.DepthWriteMask = (D3D11_DEPTH_WRITE_MASK)pEntry->depthWriteMask;
1929 desc.DepthFunc = (D3D11_COMPARISON_FUNC)pEntry->depthFunc;
1930 desc.StencilEnable = pEntry->stencilEnable;
1931 desc.StencilReadMask = pEntry->stencilReadMask;
1932 desc.StencilWriteMask = pEntry->stencilWriteMask;
1933 desc.FrontFace.StencilFailOp = (D3D11_STENCIL_OP)pEntry->frontStencilFailOp;
1934 desc.FrontFace.StencilDepthFailOp = (D3D11_STENCIL_OP)pEntry->frontStencilDepthFailOp;
1935 desc.FrontFace.StencilPassOp = (D3D11_STENCIL_OP)pEntry->frontStencilPassOp;
1936 desc.FrontFace.StencilFunc = (D3D11_COMPARISON_FUNC)pEntry->frontStencilFunc;
1937 desc.BackFace.StencilFailOp = (D3D11_STENCIL_OP)pEntry->backStencilFailOp;
1938 desc.BackFace.StencilDepthFailOp = (D3D11_STENCIL_OP)pEntry->backStencilDepthFailOp;
1939 desc.BackFace.StencilPassOp = (D3D11_STENCIL_OP)pEntry->backStencilPassOp;
1940 desc.BackFace.StencilFunc = (D3D11_COMPARISON_FUNC)pEntry->backStencilFunc;
1941 /** @todo frontEnable, backEnable */
1942
1943 HRESULT hr = pDevice->pDevice->CreateDepthStencilState(&desc, pp);
1944 Assert(SUCCEEDED(hr));
1945 return hr;
1946}
1947
1948
1949static HRESULT dxSamplerStateCreate(DXDEVICE *pDevice, SVGACOTableDXSamplerEntry const *pEntry, ID3D11SamplerState **pp)
1950{
1951 D3D11_SAMPLER_DESC desc;
1952 /* Guest sometimes sends inconsistent (from D3D11 point of view) set of filter flags. */
1953 if (pEntry->filter & SVGA3D_FILTER_ANISOTROPIC)
1954 desc.Filter = (pEntry->filter & SVGA3D_FILTER_COMPARE)
1955 ? D3D11_FILTER_COMPARISON_ANISOTROPIC
1956 : D3D11_FILTER_ANISOTROPIC;
1957 else
1958 desc.Filter = (D3D11_FILTER)pEntry->filter;
1959 desc.AddressU = (D3D11_TEXTURE_ADDRESS_MODE)pEntry->addressU;
1960 desc.AddressV = (D3D11_TEXTURE_ADDRESS_MODE)pEntry->addressV;
1961 desc.AddressW = (D3D11_TEXTURE_ADDRESS_MODE)pEntry->addressW;
1962 desc.MipLODBias = pEntry->mipLODBias;
1963 desc.MaxAnisotropy = RT_CLAMP(pEntry->maxAnisotropy, 1, 16); /* "Valid values are between 1 and 16" */
1964 desc.ComparisonFunc = (D3D11_COMPARISON_FUNC)pEntry->comparisonFunc;
1965 desc.BorderColor[0] = pEntry->borderColor.value[0];
1966 desc.BorderColor[1] = pEntry->borderColor.value[1];
1967 desc.BorderColor[2] = pEntry->borderColor.value[2];
1968 desc.BorderColor[3] = pEntry->borderColor.value[3];
1969 desc.MinLOD = pEntry->minLOD;
1970 desc.MaxLOD = pEntry->maxLOD;
1971
1972 HRESULT hr = pDevice->pDevice->CreateSamplerState(&desc, pp);
1973 Assert(SUCCEEDED(hr));
1974 return hr;
1975}
1976
1977
1978static D3D11_FILL_MODE dxFillMode(uint8_t svgaFillMode)
1979{
1980 if (svgaFillMode == SVGA3D_FILLMODE_POINT)
1981 return D3D11_FILL_WIREFRAME;
1982 return (D3D11_FILL_MODE)svgaFillMode;
1983}
1984
1985
1986static D3D11_CULL_MODE dxCullMode(uint8_t svgaCullMode)
1987{
1988 return (D3D11_CULL_MODE)svgaCullMode;
1989}
1990
1991
1992static HRESULT dxRasterizerStateCreate(DXDEVICE *pDevice, SVGACOTableDXRasterizerStateEntry const *pEntry, ID3D11RasterizerState1 **pp)
1993{
1994 D3D11_RASTERIZER_DESC1 desc;
1995 desc.FillMode = dxFillMode(pEntry->fillMode);
1996 desc.CullMode = dxCullMode(pEntry->cullMode);
1997 desc.FrontCounterClockwise = pEntry->frontCounterClockwise;
1998 /** @todo provokingVertexLast */
1999 desc.DepthBias = pEntry->depthBias;
2000 desc.DepthBiasClamp = pEntry->depthBiasClamp;
2001 desc.SlopeScaledDepthBias = pEntry->slopeScaledDepthBias;
2002 desc.DepthClipEnable = pEntry->depthClipEnable;
2003 desc.ScissorEnable = pEntry->scissorEnable;
2004 desc.MultisampleEnable = pEntry->multisampleEnable;
2005 desc.AntialiasedLineEnable = pEntry->antialiasedLineEnable;
2006 desc.ForcedSampleCount = pEntry->forcedSampleCount;
2007 /** @todo lineWidth lineStippleEnable lineStippleFactor lineStipplePattern */
2008
2009 HRESULT hr = pDevice->pDevice->CreateRasterizerState1(&desc, pp);
2010 Assert(SUCCEEDED(hr));
2011 return hr;
2012}
2013
2014
2015static HRESULT dxRenderTargetViewCreate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableDXRTViewEntry const *pEntry, VMSVGA3DSURFACE *pSurface, ID3D11RenderTargetView **pp)
2016{
2017 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
2018
2019 ID3D11Resource *pResource = dxResource(pThisCC->svga.p3dState, pSurface, pDXContext);
2020
2021 D3D11_RENDER_TARGET_VIEW_DESC desc;
2022 RT_ZERO(desc);
2023 desc.Format = vmsvgaDXSurfaceFormat2Dxgi(pEntry->format);
2024 AssertReturn(desc.Format != DXGI_FORMAT_UNKNOWN || pEntry->format == SVGA3D_BUFFER, E_FAIL);
2025 switch (pEntry->resourceDimension)
2026 {
2027 case SVGA3D_RESOURCE_BUFFER:
2028 desc.ViewDimension = D3D11_RTV_DIMENSION_BUFFER;
2029 desc.Buffer.FirstElement = pEntry->desc.buffer.firstElement;
2030 desc.Buffer.NumElements = pEntry->desc.buffer.numElements;
2031 break;
2032 case SVGA3D_RESOURCE_TEXTURE1D:
2033 if (pSurface->surfaceDesc.numArrayElements <= 1)
2034 {
2035 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D;
2036 desc.Texture1D.MipSlice = pEntry->desc.tex.mipSlice;
2037 }
2038 else
2039 {
2040 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY;
2041 desc.Texture1DArray.MipSlice = pEntry->desc.tex.mipSlice;
2042 desc.Texture1DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
2043 desc.Texture1DArray.ArraySize = pEntry->desc.tex.arraySize;
2044 }
2045 break;
2046 case SVGA3D_RESOURCE_TEXTURE2D:
2047 if (pSurface->surfaceDesc.numArrayElements <= 1)
2048 {
2049 desc.ViewDimension = pSurface->surfaceDesc.multisampleCount > 1
2050 ? D3D11_RTV_DIMENSION_TEXTURE2DMS
2051 : D3D11_RTV_DIMENSION_TEXTURE2D;
2052 desc.Texture2D.MipSlice = pEntry->desc.tex.mipSlice;
2053 }
2054 else
2055 {
2056 desc.ViewDimension = pSurface->surfaceDesc.multisampleCount > 1
2057 ? D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY
2058 : D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
2059 desc.Texture2DArray.MipSlice = pEntry->desc.tex.mipSlice;
2060 desc.Texture2DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
2061 desc.Texture2DArray.ArraySize = pEntry->desc.tex.arraySize;
2062 }
2063 break;
2064 case SVGA3D_RESOURCE_TEXTURE3D:
2065 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
2066 desc.Texture3D.MipSlice = pEntry->desc.tex3D.mipSlice;
2067 desc.Texture3D.FirstWSlice = pEntry->desc.tex3D.firstW;
2068 desc.Texture3D.WSize = pEntry->desc.tex3D.wSize;
2069 break;
2070 case SVGA3D_RESOURCE_TEXTURECUBE:
2071 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
2072 desc.Texture2DArray.MipSlice = pEntry->desc.tex.mipSlice;
2073 desc.Texture2DArray.FirstArraySlice = 0;
2074 desc.Texture2DArray.ArraySize = 6;
2075 break;
2076 case SVGA3D_RESOURCE_BUFFEREX:
2077 AssertFailed(); /** @todo test. Probably not applicable to a render target view. */
2078 desc.ViewDimension = D3D11_RTV_DIMENSION_BUFFER;
2079 desc.Buffer.FirstElement = pEntry->desc.buffer.firstElement;
2080 desc.Buffer.NumElements = pEntry->desc.buffer.numElements;
2081 break;
2082 default:
2083 ASSERT_GUEST_FAILED_RETURN(E_INVALIDARG);
2084 }
2085
2086 HRESULT hr = pDevice->pDevice->CreateRenderTargetView(pResource, &desc, pp);
2087 Assert(SUCCEEDED(hr));
2088 return hr;
2089}
2090
2091
2092static HRESULT dxShaderResourceViewCreate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableDXSRViewEntry const *pEntry, VMSVGA3DSURFACE *pSurface, ID3D11ShaderResourceView **pp)
2093{
2094 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
2095
2096 ID3D11Resource *pResource = dxResource(pThisCC->svga.p3dState, pSurface, pDXContext);
2097
2098 D3D11_SHADER_RESOURCE_VIEW_DESC desc;
2099 RT_ZERO(desc);
2100 desc.Format = vmsvgaDXSurfaceFormat2Dxgi(pEntry->format);
2101 AssertReturn(desc.Format != DXGI_FORMAT_UNKNOWN || pEntry->format == SVGA3D_BUFFER, E_FAIL);
2102
2103 switch (pEntry->resourceDimension)
2104 {
2105 case SVGA3D_RESOURCE_BUFFER:
2106 desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
2107 desc.Buffer.FirstElement = pEntry->desc.buffer.firstElement;
2108 desc.Buffer.NumElements = pEntry->desc.buffer.numElements;
2109 break;
2110 case SVGA3D_RESOURCE_TEXTURE1D:
2111 if (pSurface->surfaceDesc.numArrayElements <= 1)
2112 {
2113 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
2114 desc.Texture1D.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
2115 desc.Texture1D.MipLevels = pEntry->desc.tex.mipLevels;
2116 }
2117 else
2118 {
2119 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY;
2120 desc.Texture1DArray.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
2121 desc.Texture1DArray.MipLevels = pEntry->desc.tex.mipLevels;
2122 desc.Texture1DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
2123 desc.Texture1DArray.ArraySize = pEntry->desc.tex.arraySize;
2124 }
2125 break;
2126 case SVGA3D_RESOURCE_TEXTURE2D:
2127 if (pSurface->surfaceDesc.numArrayElements <= 1)
2128 {
2129 desc.ViewDimension = pSurface->surfaceDesc.multisampleCount > 1
2130 ? D3D11_SRV_DIMENSION_TEXTURE2DMS
2131 : D3D11_SRV_DIMENSION_TEXTURE2D;
2132 desc.Texture2D.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
2133 desc.Texture2D.MipLevels = pEntry->desc.tex.mipLevels;
2134 }
2135 else
2136 {
2137 desc.ViewDimension = pSurface->surfaceDesc.multisampleCount > 1
2138 ? D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY
2139 : D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
2140 desc.Texture2DArray.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
2141 desc.Texture2DArray.MipLevels = pEntry->desc.tex.mipLevels;
2142 desc.Texture2DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
2143 desc.Texture2DArray.ArraySize = pEntry->desc.tex.arraySize;
2144 }
2145 break;
2146 case SVGA3D_RESOURCE_TEXTURE3D:
2147 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
2148 desc.Texture3D.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
2149 desc.Texture3D.MipLevels = pEntry->desc.tex.mipLevels;
2150 break;
2151 case SVGA3D_RESOURCE_TEXTURECUBE:
2152 if (pSurface->surfaceDesc.numArrayElements <= 6)
2153 {
2154 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
2155 desc.TextureCube.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
2156 desc.TextureCube.MipLevels = pEntry->desc.tex.mipLevels;
2157 }
2158 else
2159 {
2160 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
2161 desc.TextureCubeArray.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
2162 desc.TextureCubeArray.MipLevels = pEntry->desc.tex.mipLevels;
2163 desc.TextureCubeArray.First2DArrayFace = pEntry->desc.tex.firstArraySlice;
2164 desc.TextureCubeArray.NumCubes = pEntry->desc.tex.arraySize / 6;
2165 }
2166 break;
2167 case SVGA3D_RESOURCE_BUFFEREX:
2168 AssertFailed(); /** @todo test. */
2169 desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
2170 desc.BufferEx.FirstElement = pEntry->desc.bufferex.firstElement;
2171 desc.BufferEx.NumElements = pEntry->desc.bufferex.numElements;
2172 desc.BufferEx.Flags = pEntry->desc.bufferex.flags;
2173 break;
2174 default:
2175 ASSERT_GUEST_FAILED_RETURN(E_INVALIDARG);
2176 }
2177
2178 HRESULT hr = pDevice->pDevice->CreateShaderResourceView(pResource, &desc, pp);
2179 Assert(SUCCEEDED(hr));
2180 return hr;
2181}
2182
2183
2184static HRESULT dxUnorderedAccessViewCreate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableDXUAViewEntry const *pEntry, VMSVGA3DSURFACE *pSurface, ID3D11UnorderedAccessView **pp)
2185{
2186 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
2187
2188 ID3D11Resource *pResource = dxResource(pThisCC->svga.p3dState, pSurface, pDXContext);
2189
2190 D3D11_UNORDERED_ACCESS_VIEW_DESC desc;
2191 RT_ZERO(desc);
2192 desc.Format = vmsvgaDXSurfaceFormat2Dxgi(pEntry->format);
2193 AssertReturn(desc.Format != DXGI_FORMAT_UNKNOWN || pEntry->format == SVGA3D_BUFFER, E_FAIL);
2194
2195 switch (pEntry->resourceDimension)
2196 {
2197 case SVGA3D_RESOURCE_BUFFER:
2198 desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
2199 desc.Buffer.FirstElement = pEntry->desc.buffer.firstElement;
2200 desc.Buffer.NumElements = pEntry->desc.buffer.numElements;
2201 desc.Buffer.Flags = pEntry->desc.buffer.flags;
2202 break;
2203 case SVGA3D_RESOURCE_TEXTURE1D:
2204 if (pSurface->surfaceDesc.numArrayElements <= 1)
2205 {
2206 desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1D;
2207 desc.Texture1D.MipSlice = pEntry->desc.tex.mipSlice;
2208 }
2209 else
2210 {
2211 desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1DARRAY;
2212 desc.Texture1DArray.MipSlice = pEntry->desc.tex.mipSlice;
2213 desc.Texture1DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
2214 desc.Texture1DArray.ArraySize = pEntry->desc.tex.arraySize;
2215 }
2216 break;
2217 case SVGA3D_RESOURCE_TEXTURE2D:
2218 if (pSurface->surfaceDesc.numArrayElements <= 1)
2219 {
2220 desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
2221 desc.Texture2D.MipSlice = pEntry->desc.tex.mipSlice;
2222 }
2223 else
2224 {
2225 desc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
2226 desc.Texture2DArray.MipSlice = pEntry->desc.tex.mipSlice;
2227 desc.Texture2DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
2228 desc.Texture2DArray.ArraySize = pEntry->desc.tex.arraySize;
2229 }
2230 break;
2231 case SVGA3D_RESOURCE_TEXTURE3D:
2232 desc.Texture3D.MipSlice = pEntry->desc.tex3D.mipSlice;
2233 desc.Texture3D.FirstWSlice = pEntry->desc.tex3D.firstW;
2234 desc.Texture3D.WSize = pEntry->desc.tex3D.wSize;
2235 break;
2236 default:
2237 ASSERT_GUEST_FAILED_RETURN(E_INVALIDARG);
2238 }
2239
2240 HRESULT hr = pDevice->pDevice->CreateUnorderedAccessView(pResource, &desc, pp);
2241 Assert(SUCCEEDED(hr));
2242 return hr;
2243}
2244
2245
2246static HRESULT dxDepthStencilViewCreate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableDXDSViewEntry const *pEntry, VMSVGA3DSURFACE *pSurface, ID3D11DepthStencilView **pp)
2247{
2248 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
2249
2250 ID3D11Resource *pResource = dxResource(pThisCC->svga.p3dState, pSurface, pDXContext);
2251
2252 D3D11_DEPTH_STENCIL_VIEW_DESC desc;
2253 RT_ZERO(desc);
2254 desc.Format = vmsvgaDXSurfaceFormat2Dxgi(pEntry->format);
2255 AssertReturn(desc.Format != DXGI_FORMAT_UNKNOWN || pEntry->format == SVGA3D_BUFFER, E_FAIL);
2256 desc.Flags = pEntry->flags;
2257 switch (pEntry->resourceDimension)
2258 {
2259 case SVGA3D_RESOURCE_TEXTURE1D:
2260 if (pSurface->surfaceDesc.numArrayElements <= 1)
2261 {
2262 desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D;
2263 desc.Texture1D.MipSlice = pEntry->mipSlice;
2264 }
2265 else
2266 {
2267 desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY;
2268 desc.Texture1DArray.MipSlice = pEntry->mipSlice;
2269 desc.Texture1DArray.FirstArraySlice = pEntry->firstArraySlice;
2270 desc.Texture1DArray.ArraySize = pEntry->arraySize;
2271 }
2272 break;
2273 case SVGA3D_RESOURCE_TEXTURE2D:
2274 if (pSurface->surfaceDesc.numArrayElements <= 1)
2275 {
2276 desc.ViewDimension = pSurface->surfaceDesc.multisampleCount > 1
2277 ? D3D11_DSV_DIMENSION_TEXTURE2DMS
2278 : D3D11_DSV_DIMENSION_TEXTURE2D;
2279 desc.Texture2D.MipSlice = pEntry->mipSlice;
2280 }
2281 else
2282 {
2283 desc.ViewDimension = pSurface->surfaceDesc.multisampleCount > 1
2284 ? D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY
2285 : D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
2286 desc.Texture2DArray.MipSlice = pEntry->mipSlice;
2287 desc.Texture2DArray.FirstArraySlice = pEntry->firstArraySlice;
2288 desc.Texture2DArray.ArraySize = pEntry->arraySize;
2289 }
2290 break;
2291 default:
2292 ASSERT_GUEST_FAILED_RETURN(E_INVALIDARG);
2293 }
2294
2295 HRESULT hr = pDevice->pDevice->CreateDepthStencilView(pResource, &desc, pp);
2296 Assert(SUCCEEDED(hr));
2297 return hr;
2298}
2299
2300
2301static HRESULT dxShaderCreate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, DXSHADER *pDXShader)
2302{
2303 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
2304
2305 HRESULT hr = S_OK;
2306
2307 switch (pDXShader->enmShaderType)
2308 {
2309 case SVGA3D_SHADERTYPE_VS:
2310 hr = pDevice->pDevice->CreateVertexShader(pDXShader->pvDXBC, pDXShader->cbDXBC, NULL, &pDXShader->pVertexShader);
2311 Assert(SUCCEEDED(hr));
2312 break;
2313 case SVGA3D_SHADERTYPE_PS:
2314 hr = pDevice->pDevice->CreatePixelShader(pDXShader->pvDXBC, pDXShader->cbDXBC, NULL, &pDXShader->pPixelShader);
2315 Assert(SUCCEEDED(hr));
2316 break;
2317 case SVGA3D_SHADERTYPE_GS:
2318 {
2319 SVGA3dStreamOutputId const soid = pDXContext->svgaDXContext.streamOut.soid;
2320 if (soid == SVGA_ID_INVALID)
2321 {
2322 hr = pDevice->pDevice->CreateGeometryShader(pDXShader->pvDXBC, pDXShader->cbDXBC, NULL, &pDXShader->pGeometryShader);
2323 Assert(SUCCEEDED(hr));
2324 }
2325 else
2326 {
2327 ASSERT_GUEST_RETURN(soid < pDXContext->pBackendDXContext->cStreamOutput, E_INVALIDARG);
2328
2329 SVGACOTableDXStreamOutputEntry const *pEntry = &pDXContext->cot.paStreamOutput[soid];
2330 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
2331
2332 hr = pDevice->pDevice->CreateGeometryShaderWithStreamOutput(pDXShader->pvDXBC, pDXShader->cbDXBC,
2333 pDXStreamOutput->aDeclarationEntry, pDXStreamOutput->cDeclarationEntry,
2334 pEntry->numOutputStreamStrides ? pEntry->streamOutputStrideInBytes : NULL, pEntry->numOutputStreamStrides,
2335 pEntry->rasterizedStream,
2336 /*pClassLinkage=*/ NULL, &pDXShader->pGeometryShader);
2337 AssertBreak(SUCCEEDED(hr));
2338
2339 pDXShader->soid = soid;
2340 }
2341 break;
2342 }
2343 case SVGA3D_SHADERTYPE_HS:
2344 hr = pDevice->pDevice->CreateHullShader(pDXShader->pvDXBC, pDXShader->cbDXBC, NULL, &pDXShader->pHullShader);
2345 Assert(SUCCEEDED(hr));
2346 break;
2347 case SVGA3D_SHADERTYPE_DS:
2348 hr = pDevice->pDevice->CreateDomainShader(pDXShader->pvDXBC, pDXShader->cbDXBC, NULL, &pDXShader->pDomainShader);
2349 Assert(SUCCEEDED(hr));
2350 break;
2351 case SVGA3D_SHADERTYPE_CS:
2352 hr = pDevice->pDevice->CreateComputeShader(pDXShader->pvDXBC, pDXShader->cbDXBC, NULL, &pDXShader->pComputeShader);
2353 Assert(SUCCEEDED(hr));
2354 break;
2355 default:
2356 ASSERT_GUEST_FAILED_RETURN(E_INVALIDARG);
2357 }
2358
2359 return hr;
2360}
2361
2362
2363static void dxShaderSet(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderType type, DXSHADER *pDXShader)
2364{
2365 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
2366
2367 switch (type)
2368 {
2369 case SVGA3D_SHADERTYPE_VS:
2370 pDevice->pImmediateContext->VSSetShader(pDXShader ? pDXShader->pVertexShader : NULL, NULL, 0);
2371 break;
2372 case SVGA3D_SHADERTYPE_PS:
2373 pDevice->pImmediateContext->PSSetShader(pDXShader ? pDXShader->pPixelShader : NULL, NULL, 0);
2374 break;
2375 case SVGA3D_SHADERTYPE_GS:
2376 {
2377 Assert(!pDXShader || (pDXShader->soid == pDXContext->svgaDXContext.streamOut.soid));
2378 pDevice->pImmediateContext->GSSetShader(pDXShader ? pDXShader->pGeometryShader : NULL, NULL, 0);
2379 } break;
2380 case SVGA3D_SHADERTYPE_HS:
2381 pDevice->pImmediateContext->HSSetShader(pDXShader ? pDXShader->pHullShader : NULL, NULL, 0);
2382 break;
2383 case SVGA3D_SHADERTYPE_DS:
2384 pDevice->pImmediateContext->DSSetShader(pDXShader ? pDXShader->pDomainShader : NULL, NULL, 0);
2385 break;
2386 case SVGA3D_SHADERTYPE_CS:
2387 pDevice->pImmediateContext->CSSetShader(pDXShader ? pDXShader->pComputeShader : NULL, NULL, 0);
2388 break;
2389 default:
2390 ASSERT_GUEST_FAILED_RETURN_VOID();
2391 }
2392}
2393
2394
2395static void dxConstantBufferSet(DXDEVICE *pDevice, uint32_t slot, SVGA3dShaderType type, ID3D11Buffer *pConstantBuffer)
2396{
2397 switch (type)
2398 {
2399 case SVGA3D_SHADERTYPE_VS:
2400 pDevice->pImmediateContext->VSSetConstantBuffers(slot, 1, &pConstantBuffer);
2401 break;
2402 case SVGA3D_SHADERTYPE_PS:
2403 pDevice->pImmediateContext->PSSetConstantBuffers(slot, 1, &pConstantBuffer);
2404 break;
2405 case SVGA3D_SHADERTYPE_GS:
2406 pDevice->pImmediateContext->GSSetConstantBuffers(slot, 1, &pConstantBuffer);
2407 break;
2408 case SVGA3D_SHADERTYPE_HS:
2409 pDevice->pImmediateContext->HSSetConstantBuffers(slot, 1, &pConstantBuffer);
2410 break;
2411 case SVGA3D_SHADERTYPE_DS:
2412 pDevice->pImmediateContext->DSSetConstantBuffers(slot, 1, &pConstantBuffer);
2413 break;
2414 case SVGA3D_SHADERTYPE_CS:
2415 pDevice->pImmediateContext->CSSetConstantBuffers(slot, 1, &pConstantBuffer);
2416 break;
2417 default:
2418 ASSERT_GUEST_FAILED_RETURN_VOID();
2419 }
2420}
2421
2422
2423static void dxSamplerSet(DXDEVICE *pDevice, SVGA3dShaderType type, uint32_t startSampler, uint32_t cSampler, ID3D11SamplerState * const *papSampler)
2424{
2425 switch (type)
2426 {
2427 case SVGA3D_SHADERTYPE_VS:
2428 pDevice->pImmediateContext->VSSetSamplers(startSampler, cSampler, papSampler);
2429 break;
2430 case SVGA3D_SHADERTYPE_PS:
2431 pDevice->pImmediateContext->PSSetSamplers(startSampler, cSampler, papSampler);
2432 break;
2433 case SVGA3D_SHADERTYPE_GS:
2434 pDevice->pImmediateContext->GSSetSamplers(startSampler, cSampler, papSampler);
2435 break;
2436 case SVGA3D_SHADERTYPE_HS:
2437 pDevice->pImmediateContext->HSSetSamplers(startSampler, cSampler, papSampler);
2438 break;
2439 case SVGA3D_SHADERTYPE_DS:
2440 pDevice->pImmediateContext->DSSetSamplers(startSampler, cSampler, papSampler);
2441 break;
2442 case SVGA3D_SHADERTYPE_CS:
2443 pDevice->pImmediateContext->CSSetSamplers(startSampler, cSampler, papSampler);
2444 break;
2445 default:
2446 ASSERT_GUEST_FAILED_RETURN_VOID();
2447 }
2448}
2449
2450
2451static void dxShaderResourceViewSet(DXDEVICE *pDevice, SVGA3dShaderType type, uint32_t startView, uint32_t cShaderResourceView, ID3D11ShaderResourceView * const *papShaderResourceView)
2452{
2453 switch (type)
2454 {
2455 case SVGA3D_SHADERTYPE_VS:
2456 pDevice->pImmediateContext->VSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
2457 break;
2458 case SVGA3D_SHADERTYPE_PS:
2459 pDevice->pImmediateContext->PSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
2460 break;
2461 case SVGA3D_SHADERTYPE_GS:
2462 pDevice->pImmediateContext->GSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
2463 break;
2464 case SVGA3D_SHADERTYPE_HS:
2465 pDevice->pImmediateContext->HSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
2466 break;
2467 case SVGA3D_SHADERTYPE_DS:
2468 pDevice->pImmediateContext->DSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
2469 break;
2470 case SVGA3D_SHADERTYPE_CS:
2471 pDevice->pImmediateContext->CSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
2472 break;
2473 default:
2474 ASSERT_GUEST_FAILED_RETURN_VOID();
2475 }
2476}
2477
2478
2479static void dxCSUnorderedAccessViewSet(DXDEVICE *pDevice, uint32_t startView, uint32_t cView, ID3D11UnorderedAccessView * const *papUnorderedAccessView, UINT *pUAVInitialCounts)
2480{
2481 pDevice->pImmediateContext->CSSetUnorderedAccessViews(startView, cView, papUnorderedAccessView, pUAVInitialCounts);
2482}
2483
2484
2485static int dxBackendSurfaceAlloc(PVMSVGA3DBACKENDSURFACE *ppBackendSurface)
2486{
2487 PVMSVGA3DBACKENDSURFACE pBackendSurface = (PVMSVGA3DBACKENDSURFACE)RTMemAllocZ(sizeof(VMSVGA3DBACKENDSURFACE));
2488 AssertPtrReturn(pBackendSurface, VERR_NO_MEMORY);
2489 pBackendSurface->cidDrawing = SVGA_ID_INVALID;
2490 RTListInit(&pBackendSurface->listView);
2491 *ppBackendSurface = pBackendSurface;
2492 return VINF_SUCCESS;
2493}
2494
2495
2496static HRESULT dxInitSharedHandle(PVMSVGA3DBACKEND pBackend, PVMSVGA3DBACKENDSURFACE pBackendSurface)
2497{
2498 if (pBackend->fSingleDevice)
2499 return S_OK;
2500
2501 /* Get the shared handle. */
2502 IDXGIResource *pDxgiResource = NULL;
2503 HRESULT hr = pBackendSurface->u.pResource->QueryInterface(__uuidof(IDXGIResource), (void**)&pDxgiResource);
2504 Assert(SUCCEEDED(hr));
2505 if (SUCCEEDED(hr))
2506 {
2507 hr = pDxgiResource->GetSharedHandle(&pBackendSurface->SharedHandle);
2508 Assert(SUCCEEDED(hr));
2509 D3D_RELEASE(pDxgiResource);
2510 }
2511
2512 return hr;
2513}
2514
2515
2516static UINT dxBindFlags(SVGA3dSurfaceAllFlags surfaceFlags)
2517{
2518 /* Catch unimplemented flags. */
2519 Assert(!RT_BOOL(surfaceFlags & (SVGA3D_SURFACE_BIND_LOGICOPS | SVGA3D_SURFACE_BIND_RAW_VIEWS)));
2520
2521 UINT BindFlags = 0;
2522
2523 if (surfaceFlags & (SVGA3D_SURFACE_BIND_VERTEX_BUFFER | SVGA3D_SURFACE_HINT_VERTEXBUFFER))
2524 BindFlags |= D3D11_BIND_VERTEX_BUFFER;
2525 if (surfaceFlags & (SVGA3D_SURFACE_BIND_INDEX_BUFFER | SVGA3D_SURFACE_HINT_INDEXBUFFER))
2526 BindFlags |= D3D11_BIND_INDEX_BUFFER;
2527 if (surfaceFlags & SVGA3D_SURFACE_BIND_CONSTANT_BUFFER) BindFlags |= D3D11_BIND_CONSTANT_BUFFER;
2528 if (surfaceFlags & SVGA3D_SURFACE_BIND_SHADER_RESOURCE) BindFlags |= D3D11_BIND_SHADER_RESOURCE;
2529 if (surfaceFlags & SVGA3D_SURFACE_BIND_RENDER_TARGET) BindFlags |= D3D11_BIND_RENDER_TARGET;
2530 if (surfaceFlags & SVGA3D_SURFACE_BIND_DEPTH_STENCIL) BindFlags |= D3D11_BIND_DEPTH_STENCIL;
2531 if (surfaceFlags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) BindFlags |= D3D11_BIND_STREAM_OUTPUT;
2532 if (surfaceFlags & SVGA3D_SURFACE_BIND_UAVIEW) BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
2533 if (surfaceFlags & SVGA3D_SURFACE_RESERVED1) BindFlags |= D3D11_BIND_DECODER;
2534
2535 return BindFlags;
2536}
2537
2538
2539static DXDEVICE *dxSurfaceDevice(PVMSVGA3DSTATE p3dState, PVMSVGA3DSURFACE pSurface, PVMSVGA3DDXCONTEXT pDXContext, UINT *pMiscFlags)
2540{
2541 if (p3dState->pBackend->fSingleDevice)
2542 {
2543 *pMiscFlags = 0;
2544 return &p3dState->pBackend->dxDevice;
2545 }
2546
2547 if (!pDXContext || dxIsSurfaceShareable(pSurface))
2548 {
2549 *pMiscFlags = D3D11_RESOURCE_MISC_SHARED;
2550 return &p3dState->pBackend->dxDevice;
2551 }
2552
2553 *pMiscFlags = 0;
2554 return &pDXContext->pBackendDXContext->dxDevice;
2555}
2556
2557
2558static DXGI_FORMAT dxGetDxgiTypelessFormat(DXGI_FORMAT dxgiFormat)
2559{
2560 switch (dxgiFormat)
2561 {
2562 case DXGI_FORMAT_R32G32B32A32_FLOAT:
2563 case DXGI_FORMAT_R32G32B32A32_UINT:
2564 case DXGI_FORMAT_R32G32B32A32_SINT:
2565 return DXGI_FORMAT_R32G32B32A32_TYPELESS; /* 1 */
2566 case DXGI_FORMAT_R32G32B32_FLOAT:
2567 case DXGI_FORMAT_R32G32B32_UINT:
2568 case DXGI_FORMAT_R32G32B32_SINT:
2569 return DXGI_FORMAT_R32G32B32_TYPELESS; /* 5 */
2570 case DXGI_FORMAT_R16G16B16A16_FLOAT:
2571 case DXGI_FORMAT_R16G16B16A16_UNORM:
2572 case DXGI_FORMAT_R16G16B16A16_UINT:
2573 case DXGI_FORMAT_R16G16B16A16_SNORM:
2574 case DXGI_FORMAT_R16G16B16A16_SINT:
2575 return DXGI_FORMAT_R16G16B16A16_TYPELESS; /* 9 */
2576 case DXGI_FORMAT_R32G32_FLOAT:
2577 case DXGI_FORMAT_R32G32_UINT:
2578 case DXGI_FORMAT_R32G32_SINT:
2579 return DXGI_FORMAT_R32G32_TYPELESS; /* 15 */
2580 case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
2581 case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
2582 case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
2583 return DXGI_FORMAT_R32G8X24_TYPELESS; /* 19 */
2584 case DXGI_FORMAT_R10G10B10A2_UNORM:
2585 case DXGI_FORMAT_R10G10B10A2_UINT:
2586 return DXGI_FORMAT_R10G10B10A2_TYPELESS; /* 23 */
2587 case DXGI_FORMAT_R8G8B8A8_UNORM:
2588 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
2589 case DXGI_FORMAT_R8G8B8A8_UINT:
2590 case DXGI_FORMAT_R8G8B8A8_SNORM:
2591 case DXGI_FORMAT_R8G8B8A8_SINT:
2592 return DXGI_FORMAT_R8G8B8A8_TYPELESS; /* 27 */
2593 case DXGI_FORMAT_R16G16_FLOAT:
2594 case DXGI_FORMAT_R16G16_UNORM:
2595 case DXGI_FORMAT_R16G16_UINT:
2596 case DXGI_FORMAT_R16G16_SNORM:
2597 case DXGI_FORMAT_R16G16_SINT:
2598 return DXGI_FORMAT_R16G16_TYPELESS; /* 33 */
2599 case DXGI_FORMAT_D32_FLOAT:
2600 case DXGI_FORMAT_R32_FLOAT:
2601 case DXGI_FORMAT_R32_UINT:
2602 case DXGI_FORMAT_R32_SINT:
2603 return DXGI_FORMAT_R32_TYPELESS; /* 39 */
2604 case DXGI_FORMAT_D24_UNORM_S8_UINT:
2605 case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
2606 case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
2607 return DXGI_FORMAT_R24G8_TYPELESS; /* 44 */
2608 case DXGI_FORMAT_R8G8_UNORM:
2609 case DXGI_FORMAT_R8G8_UINT:
2610 case DXGI_FORMAT_R8G8_SNORM:
2611 case DXGI_FORMAT_R8G8_SINT:
2612 return DXGI_FORMAT_R8G8_TYPELESS; /* 48*/
2613 case DXGI_FORMAT_R16_FLOAT:
2614 case DXGI_FORMAT_D16_UNORM:
2615 case DXGI_FORMAT_R16_UNORM:
2616 case DXGI_FORMAT_R16_UINT:
2617 case DXGI_FORMAT_R16_SNORM:
2618 case DXGI_FORMAT_R16_SINT:
2619 return DXGI_FORMAT_R16_TYPELESS; /* 53 */
2620 case DXGI_FORMAT_R8_UNORM:
2621 case DXGI_FORMAT_R8_UINT:
2622 case DXGI_FORMAT_R8_SNORM:
2623 case DXGI_FORMAT_R8_SINT:
2624 return DXGI_FORMAT_R8_TYPELESS; /* 60*/
2625 case DXGI_FORMAT_BC1_UNORM:
2626 case DXGI_FORMAT_BC1_UNORM_SRGB:
2627 return DXGI_FORMAT_BC1_TYPELESS; /* 70 */
2628 case DXGI_FORMAT_BC2_UNORM:
2629 case DXGI_FORMAT_BC2_UNORM_SRGB:
2630 return DXGI_FORMAT_BC2_TYPELESS; /* 73 */
2631 case DXGI_FORMAT_BC3_UNORM:
2632 case DXGI_FORMAT_BC3_UNORM_SRGB:
2633 return DXGI_FORMAT_BC3_TYPELESS; /* 76 */
2634 case DXGI_FORMAT_BC4_UNORM:
2635 case DXGI_FORMAT_BC4_SNORM:
2636 return DXGI_FORMAT_BC4_TYPELESS; /* 79 */
2637 case DXGI_FORMAT_BC5_UNORM:
2638 case DXGI_FORMAT_BC5_SNORM:
2639 return DXGI_FORMAT_BC5_TYPELESS; /* 82 */
2640 case DXGI_FORMAT_B8G8R8A8_UNORM:
2641 case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
2642 return DXGI_FORMAT_B8G8R8A8_TYPELESS; /* 90 */
2643 case DXGI_FORMAT_B8G8R8X8_UNORM:
2644 case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
2645 return DXGI_FORMAT_B8G8R8X8_TYPELESS; /* 92 */
2646 case DXGI_FORMAT_BC6H_UF16:
2647 case DXGI_FORMAT_BC6H_SF16:
2648 return DXGI_FORMAT_BC6H_TYPELESS; /* 94 */
2649 case DXGI_FORMAT_BC7_UNORM:
2650 case DXGI_FORMAT_BC7_UNORM_SRGB:
2651 return DXGI_FORMAT_BC7_TYPELESS; /* 97 */
2652 default:
2653 break;
2654 }
2655
2656 return dxgiFormat;
2657}
2658
2659
2660static bool dxIsDepthStencilFormat(DXGI_FORMAT dxgiFormat)
2661{
2662 switch (dxgiFormat)
2663 {
2664 case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
2665 case DXGI_FORMAT_D32_FLOAT:
2666 case DXGI_FORMAT_D24_UNORM_S8_UINT:
2667 case DXGI_FORMAT_D16_UNORM:
2668 return true;
2669 default:
2670 break;
2671 }
2672
2673 return false;
2674}
2675
2676
2677static int vmsvga3dBackSurfaceCreateTexture(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
2678{
2679 PVMSVGA3DSTATE p3dState = pThisCC->svga.p3dState;
2680 AssertReturn(p3dState, VERR_INVALID_STATE);
2681
2682 PVMSVGA3DBACKEND pBackend = p3dState->pBackend;
2683 AssertReturn(pBackend, VERR_INVALID_STATE);
2684
2685 UINT MiscFlags;
2686 DXDEVICE *pDXDevice = dxSurfaceDevice(p3dState, pSurface, pDXContext, &MiscFlags);
2687 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
2688
2689 if (pSurface->pBackendSurface != NULL)
2690 {
2691 AssertFailed(); /** @todo Should the function not be used like that? */
2692 vmsvga3dBackSurfaceDestroy(pThisCC, false, pSurface);
2693 }
2694
2695 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2696 int rc = dxBackendSurfaceAlloc(&pBackendSurface);
2697 AssertRCReturn(rc, rc);
2698
2699 uint32_t const cWidth = pSurface->paMipmapLevels[0].cBlocksX * pSurface->cxBlock;
2700 uint32_t const cHeight = pSurface->paMipmapLevels[0].cBlocksY * pSurface->cyBlock;
2701 uint32_t const cDepth = pSurface->paMipmapLevels[0].mipmapSize.depth;
2702 uint32_t const numMipLevels = pSurface->cLevels;
2703
2704 DXGI_FORMAT dxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(pSurface->format);
2705 AssertReturn(dxgiFormat != DXGI_FORMAT_UNKNOWN, E_FAIL);
2706
2707 /* Create typeless textures, unless it is a depth/stencil resource,
2708 * because D3D11_BIND_DEPTH_STENCIL requires a depth/stencil format.
2709 * Always use typeless format for staging/dynamic resources.
2710 * Use explicit format for screen targets. For example they can be used
2711 * for video processor output view, which does not allow a typeless format.
2712 */
2713 DXGI_FORMAT const dxgiFormatTypeless = dxGetDxgiTypelessFormat(dxgiFormat);
2714 if ( !dxIsDepthStencilFormat(dxgiFormat)
2715 && !RT_BOOL(pSurface->f.surfaceFlags & SVGA3D_SURFACE_SCREENTARGET))
2716 dxgiFormat = dxgiFormatTypeless;
2717
2718 /* Format for staging resource is always the typeless one. */
2719 DXGI_FORMAT const dxgiFormatStaging = dxgiFormatTypeless;
2720
2721 DXGI_FORMAT dxgiFormatDynamic;
2722 /* Some drivers do not allow to use depth typeless formats for dynamic resources.
2723 * Create a placeholder texture (it does not work with CopySubresource).
2724 */
2725 /** @todo Implement upload from such textures. */
2726 if (dxgiFormatTypeless == DXGI_FORMAT_R24G8_TYPELESS)
2727 dxgiFormatDynamic = DXGI_FORMAT_R32_UINT;
2728 else if (dxgiFormatTypeless == DXGI_FORMAT_R32G8X24_TYPELESS)
2729 dxgiFormatDynamic = DXGI_FORMAT_R32G32_UINT;
2730 else
2731 dxgiFormatDynamic = dxgiFormatTypeless;
2732
2733 /*
2734 * Create D3D11 texture object.
2735 */
2736 D3D11_SUBRESOURCE_DATA *paInitialData = NULL;
2737 if (pSurface->paMipmapLevels[0].pSurfaceData && pSurface->surfaceDesc.multisampleCount <= 1)
2738 {
2739 /* Can happen for a non GBO surface or if GBO texture was updated prior to creation of the hardware resource. */
2740 uint32_t const cSubresource = numMipLevels * pSurface->surfaceDesc.numArrayElements;
2741 paInitialData = (D3D11_SUBRESOURCE_DATA *)RTMemAlloc(cSubresource * sizeof(D3D11_SUBRESOURCE_DATA));
2742 AssertPtrReturn(paInitialData, VERR_NO_MEMORY);
2743
2744 for (uint32_t i = 0; i < cSubresource; ++i)
2745 {
2746 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[i];
2747 D3D11_SUBRESOURCE_DATA *p = &paInitialData[i];
2748 p->pSysMem = pMipmapLevel->pSurfaceData;
2749 p->SysMemPitch = pMipmapLevel->cbSurfacePitch;
2750 p->SysMemSlicePitch = pMipmapLevel->cbSurfacePlane;
2751 }
2752 }
2753
2754 HRESULT hr = S_OK;
2755 if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_CUBEMAP)
2756 {
2757 Assert(pSurface->cFaces == 6);
2758 Assert(cWidth == cHeight);
2759 Assert(cDepth == 1);
2760//DEBUG_BREAKPOINT_TEST();
2761
2762 D3D11_TEXTURE2D_DESC td;
2763 RT_ZERO(td);
2764 td.Width = cWidth;
2765 td.Height = cHeight;
2766 td.MipLevels = numMipLevels;
2767 td.ArraySize = pSurface->surfaceDesc.numArrayElements; /* This is 6 * numCubes */
2768 td.Format = dxgiFormat;
2769 td.SampleDesc.Count = 1;
2770 td.SampleDesc.Quality = 0;
2771 td.Usage = D3D11_USAGE_DEFAULT;
2772 td.BindFlags = dxBindFlags(pSurface->f.surfaceFlags);
2773 td.CPUAccessFlags = 0; /** @todo */
2774 td.MiscFlags = MiscFlags | D3D11_RESOURCE_MISC_TEXTURECUBE; /** @todo */
2775 if ( numMipLevels > 1
2776 && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
2777 td.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
2778
2779 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->u.pTexture2D);
2780 Assert(SUCCEEDED(hr));
2781 if (SUCCEEDED(hr))
2782 {
2783 /* Map-able texture. */
2784 td.Format = dxgiFormatDynamic;
2785 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2786 td.ArraySize = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2787 td.Usage = D3D11_USAGE_DYNAMIC;
2788 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2789 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2790 td.MiscFlags = 0;
2791 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->dynamic.pTexture2D);
2792 Assert(SUCCEEDED(hr));
2793 }
2794
2795 if (SUCCEEDED(hr))
2796 {
2797 /* Staging texture. */
2798 td.Format = dxgiFormatStaging;
2799 td.Usage = D3D11_USAGE_STAGING;
2800 td.BindFlags = 0; /* No flags allowed. */
2801 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2802 td.MiscFlags = 0;
2803 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->staging.pTexture2D);
2804 Assert(SUCCEEDED(hr));
2805 }
2806
2807 if (SUCCEEDED(hr))
2808 hr = dxInitSharedHandle(pBackend, pBackendSurface);
2809
2810 if (SUCCEEDED(hr))
2811 {
2812 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE_CUBE;
2813 }
2814 }
2815 else if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_1D)
2816 {
2817 /*
2818 * 1D texture.
2819 */
2820 Assert(pSurface->cFaces == 1);
2821
2822 D3D11_TEXTURE1D_DESC td;
2823 RT_ZERO(td);
2824 td.Width = cWidth;
2825 td.MipLevels = numMipLevels;
2826 td.ArraySize = pSurface->surfaceDesc.numArrayElements;
2827 td.Format = dxgiFormat;
2828 td.Usage = D3D11_USAGE_DEFAULT;
2829 td.BindFlags = dxBindFlags(pSurface->f.surfaceFlags);
2830 td.CPUAccessFlags = 0;
2831 td.MiscFlags = MiscFlags; /** @todo */
2832 if ( numMipLevels > 1
2833 && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
2834 td.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
2835
2836 hr = pDXDevice->pDevice->CreateTexture1D(&td, paInitialData, &pBackendSurface->u.pTexture1D);
2837 Assert(SUCCEEDED(hr));
2838 if (SUCCEEDED(hr))
2839 {
2840 /* Map-able texture. */
2841 td.Format = dxgiFormatDynamic;
2842 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2843 td.ArraySize = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2844 td.Usage = D3D11_USAGE_DYNAMIC;
2845 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2846 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2847 td.MiscFlags = 0;
2848 hr = pDXDevice->pDevice->CreateTexture1D(&td, paInitialData, &pBackendSurface->dynamic.pTexture1D);
2849 Assert(SUCCEEDED(hr));
2850 }
2851
2852 if (SUCCEEDED(hr))
2853 {
2854 /* Staging texture. */
2855 td.Format = dxgiFormatStaging;
2856 td.Usage = D3D11_USAGE_STAGING;
2857 td.BindFlags = 0; /* No flags allowed. */
2858 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2859 td.MiscFlags = 0;
2860 hr = pDXDevice->pDevice->CreateTexture1D(&td, paInitialData, &pBackendSurface->staging.pTexture1D);
2861 Assert(SUCCEEDED(hr));
2862 }
2863
2864 if (SUCCEEDED(hr))
2865 hr = dxInitSharedHandle(pBackend, pBackendSurface);
2866
2867 if (SUCCEEDED(hr))
2868 {
2869 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE_1D;
2870 }
2871 }
2872 else
2873 {
2874 if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_VOLUME)
2875 {
2876 /*
2877 * Volume texture.
2878 */
2879 Assert(pSurface->cFaces == 1);
2880 Assert(pSurface->surfaceDesc.numArrayElements == 1);
2881
2882 D3D11_TEXTURE3D_DESC td;
2883 RT_ZERO(td);
2884 td.Width = cWidth;
2885 td.Height = cHeight;
2886 td.Depth = cDepth;
2887 td.MipLevels = numMipLevels;
2888 td.Format = dxgiFormat;
2889 td.Usage = D3D11_USAGE_DEFAULT;
2890 td.BindFlags = dxBindFlags(pSurface->f.surfaceFlags);
2891 td.CPUAccessFlags = 0; /** @todo */
2892 td.MiscFlags = MiscFlags; /** @todo */
2893 if ( numMipLevels > 1
2894 && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
2895 td.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
2896
2897 hr = pDXDevice->pDevice->CreateTexture3D(&td, paInitialData, &pBackendSurface->u.pTexture3D);
2898 Assert(SUCCEEDED(hr));
2899 if (SUCCEEDED(hr))
2900 {
2901 /* Map-able texture. */
2902 td.Format = dxgiFormatDynamic;
2903 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2904 td.Usage = D3D11_USAGE_DYNAMIC;
2905 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2906 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2907 td.MiscFlags = 0;
2908 hr = pDXDevice->pDevice->CreateTexture3D(&td, paInitialData, &pBackendSurface->dynamic.pTexture3D);
2909 Assert(SUCCEEDED(hr));
2910 }
2911
2912 if (SUCCEEDED(hr))
2913 {
2914 /* Staging texture. */
2915 td.Format = dxgiFormatStaging;
2916 td.Usage = D3D11_USAGE_STAGING;
2917 td.BindFlags = 0; /* No flags allowed. */
2918 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2919 td.MiscFlags = 0;
2920 hr = pDXDevice->pDevice->CreateTexture3D(&td, paInitialData, &pBackendSurface->staging.pTexture3D);
2921 Assert(SUCCEEDED(hr));
2922 }
2923
2924 if (SUCCEEDED(hr))
2925 hr = dxInitSharedHandle(pBackend, pBackendSurface);
2926
2927 if (SUCCEEDED(hr))
2928 {
2929 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE_3D;
2930 }
2931 }
2932 else
2933 {
2934 /*
2935 * 2D texture.
2936 */
2937 Assert(cDepth == 1);
2938 Assert(pSurface->cFaces == 1);
2939
2940 D3D11_TEXTURE2D_DESC td;
2941 RT_ZERO(td);
2942 td.Width = cWidth;
2943 td.Height = cHeight;
2944 td.MipLevels = numMipLevels;
2945 td.ArraySize = pSurface->surfaceDesc.numArrayElements;
2946 td.Format = dxgiFormat;
2947 td.SampleDesc.Count = pSurface->surfaceDesc.multisampleCount;
2948 td.SampleDesc.Quality = 0;
2949 td.Usage = D3D11_USAGE_DEFAULT;
2950 td.BindFlags = dxBindFlags(pSurface->f.surfaceFlags);
2951 td.CPUAccessFlags = 0; /** @todo */
2952 td.MiscFlags = MiscFlags; /** @todo */
2953 if ( numMipLevels > 1
2954 && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
2955 td.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
2956
2957 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->u.pTexture2D);
2958 Assert(SUCCEEDED(hr));
2959 if (SUCCEEDED(hr))
2960 {
2961 /* Map-able texture. */
2962 td.Format = dxgiFormatDynamic;
2963 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2964 td.ArraySize = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2965 td.SampleDesc.Count = 1;
2966 td.SampleDesc.Quality = 0;
2967 td.Usage = D3D11_USAGE_DYNAMIC;
2968 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2969 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2970 td.MiscFlags = 0;
2971 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->dynamic.pTexture2D);
2972 Assert(SUCCEEDED(hr));
2973 }
2974
2975 if (SUCCEEDED(hr))
2976 {
2977 /* Staging texture. */
2978 td.Format = dxgiFormatStaging;
2979 td.Usage = D3D11_USAGE_STAGING;
2980 td.BindFlags = 0; /* No flags allowed. */
2981 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2982 td.MiscFlags = 0;
2983 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->staging.pTexture2D);
2984 Assert(SUCCEEDED(hr));
2985 }
2986
2987 if (SUCCEEDED(hr))
2988 hr = dxInitSharedHandle(pBackend, pBackendSurface);
2989
2990 if (SUCCEEDED(hr))
2991 {
2992 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE_2D;
2993 }
2994 }
2995 }
2996
2997 if (hr == DXGI_ERROR_DEVICE_REMOVED)
2998 {
2999 DEBUG_BREAKPOINT_TEST();
3000 hr = pDXDevice->pDevice->GetDeviceRemovedReason();
3001 }
3002
3003 Assert(hr == S_OK);
3004
3005 RTMemFree(paInitialData);
3006
3007 if (pSurface->autogenFilter != SVGA3D_TEX_FILTER_NONE)
3008 {
3009 }
3010
3011 if (SUCCEEDED(hr))
3012 {
3013 /*
3014 * Success.
3015 */
3016 LogFunc(("sid = %u\n", pSurface->id));
3017 pBackendSurface->enmDxgiFormat = dxgiFormat;
3018 pSurface->pBackendSurface = pBackendSurface;
3019 if (p3dState->pBackend->fSingleDevice || RT_BOOL(MiscFlags & D3D11_RESOURCE_MISC_SHARED))
3020 pSurface->idAssociatedContext = DX_CID_BACKEND;
3021 else
3022 pSurface->idAssociatedContext = pDXContext->cid;
3023 return VINF_SUCCESS;
3024 }
3025
3026 D3D_RELEASE(pBackendSurface->staging.pResource);
3027 D3D_RELEASE(pBackendSurface->dynamic.pResource);
3028 D3D_RELEASE(pBackendSurface->u.pResource);
3029 RTMemFree(pBackendSurface);
3030 return VERR_NO_MEMORY;
3031}
3032
3033#if 0
3034static int vmsvga3dBackSurfaceCreateBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
3035{
3036 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
3037 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
3038
3039 /* Buffers should be created as such. */
3040 AssertReturn(RT_BOOL(pSurface->f.surfaceFlags & ( SVGA3D_SURFACE_HINT_INDEXBUFFER
3041 | SVGA3D_SURFACE_HINT_VERTEXBUFFER
3042 | SVGA3D_SURFACE_BIND_VERTEX_BUFFER
3043 | SVGA3D_SURFACE_BIND_INDEX_BUFFER
3044 )), VERR_INVALID_PARAMETER);
3045
3046 if (pSurface->pBackendSurface != NULL)
3047 {
3048 AssertFailed(); /** @todo Should the function not be used like that? */
3049 vmsvga3dBackSurfaceDestroy(pThisCC, false, pSurface);
3050 }
3051
3052 PVMSVGA3DMIPMAPLEVEL pMipLevel;
3053 int rc = vmsvga3dMipmapLevel(pSurface, 0, 0, &pMipLevel);
3054 AssertRCReturn(rc, rc);
3055
3056 PVMSVGA3DBACKENDSURFACE pBackendSurface;
3057 rc = dxBackendSurfaceAlloc(&pBackendSurface);
3058 AssertRCReturn(rc, rc);
3059
3060 LogFunc(("sid = %u, size = %u\n", pSurface->id, pMipLevel->cbSurface));
3061
3062 /* Upload the current data, if any. */
3063 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
3064 D3D11_SUBRESOURCE_DATA initialData;
3065 if (pMipLevel->pSurfaceData)
3066 {
3067 initialData.pSysMem = pMipLevel->pSurfaceData;
3068 initialData.SysMemPitch = pMipLevel->cbSurface;
3069 initialData.SysMemSlicePitch = pMipLevel->cbSurface;
3070
3071 pInitialData = &initialData;
3072 }
3073
3074 D3D11_BUFFER_DESC bd;
3075 RT_ZERO(bd);
3076 bd.ByteWidth = pMipLevel->cbSurface;
3077 bd.Usage = D3D11_USAGE_DEFAULT;
3078 bd.BindFlags = dxBindFlags(pSurface->f.surfaceFlags);
3079
3080 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.pBuffer);
3081 Assert(SUCCEEDED(hr));
3082#ifndef DX_COMMON_STAGING_BUFFER
3083 if (SUCCEEDED(hr))
3084 {
3085 /* Map-able Buffer. */
3086 bd.Usage = D3D11_USAGE_DYNAMIC;
3087 bd.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
3088 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
3089 hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->dynamic.pBuffer);
3090 Assert(SUCCEEDED(hr));
3091 }
3092
3093 if (SUCCEEDED(hr))
3094 {
3095 /* Staging texture. */
3096 bd.Usage = D3D11_USAGE_STAGING;
3097 bd.BindFlags = 0; /* No flags allowed. */
3098 bd.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
3099 hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->staging.pBuffer);
3100 Assert(SUCCEEDED(hr));
3101 }
3102#endif
3103
3104 if (SUCCEEDED(hr))
3105 {
3106 /*
3107 * Success.
3108 */
3109 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
3110 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
3111 pSurface->pBackendSurface = pBackendSurface;
3112 pSurface->idAssociatedContext = pDXContext->cid;
3113 return VINF_SUCCESS;
3114 }
3115
3116 /* Failure. */
3117 D3D_RELEASE(pBackendSurface->u.pBuffer);
3118#ifndef DX_COMMON_STAGING_BUFFER
3119 D3D_RELEASE(pBackendSurface->dynamic.pBuffer);
3120 D3D_RELEASE(pBackendSurface->staging.pBuffer);
3121#endif
3122 RTMemFree(pBackendSurface);
3123 return VERR_NO_MEMORY;
3124}
3125#endif
3126
3127static int vmsvga3dBackSurfaceCreateSoBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
3128{
3129 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
3130 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
3131
3132 /* Buffers should be created as such. */
3133 AssertReturn(RT_BOOL(pSurface->f.surfaceFlags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT), VERR_INVALID_PARAMETER);
3134
3135 if (pSurface->pBackendSurface != NULL)
3136 {
3137 AssertFailed(); /** @todo Should the function not be used like that? */
3138 vmsvga3dBackSurfaceDestroy(pThisCC, false, pSurface);
3139 }
3140
3141 PVMSVGA3DBACKENDSURFACE pBackendSurface;
3142 int rc = dxBackendSurfaceAlloc(&pBackendSurface);
3143 AssertRCReturn(rc, rc);
3144
3145 D3D11_BUFFER_DESC bd;
3146 RT_ZERO(bd);
3147 bd.ByteWidth = pSurface->paMipmapLevels[0].cbSurface;
3148 bd.Usage = D3D11_USAGE_DEFAULT;
3149 bd.BindFlags = dxBindFlags(pSurface->f.surfaceFlags);
3150 bd.CPUAccessFlags = 0; /// @todo ? D3D11_CPU_ACCESS_READ;
3151 bd.MiscFlags = 0;
3152 bd.StructureByteStride = 0;
3153
3154 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, 0, &pBackendSurface->u.pBuffer);
3155#ifndef DX_COMMON_STAGING_BUFFER
3156 if (SUCCEEDED(hr))
3157 {
3158 /* Map-able Buffer. */
3159 bd.Usage = D3D11_USAGE_DYNAMIC;
3160 bd.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
3161 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
3162 hr = pDevice->pDevice->CreateBuffer(&bd, 0, &pBackendSurface->dynamic.pBuffer);
3163 Assert(SUCCEEDED(hr));
3164 }
3165
3166 if (SUCCEEDED(hr))
3167 {
3168 /* Staging texture. */
3169 bd.Usage = D3D11_USAGE_STAGING;
3170 bd.BindFlags = 0; /* No flags allowed. */
3171 bd.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
3172 hr = pDevice->pDevice->CreateBuffer(&bd, 0, &pBackendSurface->staging.pBuffer);
3173 Assert(SUCCEEDED(hr));
3174 }
3175#endif
3176
3177 if (SUCCEEDED(hr))
3178 {
3179 /*
3180 * Success.
3181 */
3182 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
3183 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
3184 pSurface->pBackendSurface = pBackendSurface;
3185 pSurface->idAssociatedContext = pDXContext->cid;
3186 return VINF_SUCCESS;
3187 }
3188
3189 /* Failure. */
3190 D3D_RELEASE(pBackendSurface->u.pBuffer);
3191#ifndef DX_COMMON_STAGING_BUFFER
3192 D3D_RELEASE(pBackendSurface->dynamic.pBuffer);
3193 D3D_RELEASE(pBackendSurface->staging.pBuffer);
3194#endif
3195 RTMemFree(pBackendSurface);
3196 return VERR_NO_MEMORY;
3197}
3198
3199#if 0
3200static int vmsvga3dBackSurfaceCreateConstantBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface, uint32_t offsetInBytes, uint32_t sizeInBytes)
3201{
3202 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
3203 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
3204
3205 /* Buffers should be created as such. */
3206 AssertReturn(RT_BOOL(pSurface->f.surfaceFlags & ( SVGA3D_SURFACE_BIND_CONSTANT_BUFFER)), VERR_INVALID_PARAMETER);
3207
3208 if (pSurface->pBackendSurface != NULL)
3209 {
3210 AssertFailed(); /** @todo Should the function not be used like that? */
3211 vmsvga3dBackSurfaceDestroy(pThisCC, false, pSurface);
3212 }
3213
3214 PVMSVGA3DMIPMAPLEVEL pMipLevel;
3215 int rc = vmsvga3dMipmapLevel(pSurface, 0, 0, &pMipLevel);
3216 AssertRCReturn(rc, rc);
3217
3218 ASSERT_GUEST_RETURN( offsetInBytes < pMipLevel->cbSurface
3219 && sizeInBytes <= pMipLevel->cbSurface - offsetInBytes, VERR_INVALID_PARAMETER);
3220
3221 PVMSVGA3DBACKENDSURFACE pBackendSurface;
3222 rc = dxBackendSurfaceAlloc(&pBackendSurface);
3223 AssertRCReturn(rc, rc);
3224
3225 /* Upload the current data, if any. */
3226 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
3227 D3D11_SUBRESOURCE_DATA initialData;
3228 if (pMipLevel->pSurfaceData)
3229 {
3230 initialData.pSysMem = (uint8_t *)pMipLevel->pSurfaceData + offsetInBytes;
3231 initialData.SysMemPitch = pMipLevel->cbSurface;
3232 initialData.SysMemSlicePitch = pMipLevel->cbSurface;
3233
3234 pInitialData = &initialData;
3235
3236 // Log(("%.*Rhxd\n", sizeInBytes, initialData.pSysMem));
3237 }
3238
3239 D3D11_BUFFER_DESC bd;
3240 RT_ZERO(bd);
3241 bd.ByteWidth = sizeInBytes;
3242 bd.Usage = D3D11_USAGE_DYNAMIC;
3243 bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
3244 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
3245 bd.MiscFlags = 0;
3246 bd.StructureByteStride = 0;
3247
3248 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.pBuffer);
3249 if (SUCCEEDED(hr))
3250 {
3251 /*
3252 * Success.
3253 */
3254 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
3255 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
3256 pSurface->pBackendSurface = pBackendSurface;
3257 pSurface->idAssociatedContext = pDXContext->cid;
3258 return VINF_SUCCESS;
3259 }
3260
3261 /* Failure. */
3262 D3D_RELEASE(pBackendSurface->u.pBuffer);
3263 RTMemFree(pBackendSurface);
3264 return VERR_NO_MEMORY;
3265}
3266#endif
3267
3268static int vmsvga3dBackSurfaceCreateResource(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
3269{
3270 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
3271 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
3272
3273 if (pSurface->pBackendSurface != NULL)
3274 {
3275 AssertFailed(); /** @todo Should the function not be used like that? */
3276 vmsvga3dBackSurfaceDestroy(pThisCC, false, pSurface);
3277 }
3278
3279 PVMSVGA3DMIPMAPLEVEL pMipLevel;
3280 int rc = vmsvga3dMipmapLevel(pSurface, 0, 0, &pMipLevel);
3281 AssertRCReturn(rc, rc);
3282
3283 PVMSVGA3DBACKENDSURFACE pBackendSurface;
3284 rc = dxBackendSurfaceAlloc(&pBackendSurface);
3285 AssertRCReturn(rc, rc);
3286
3287 HRESULT hr;
3288
3289 /*
3290 * Figure out the type of the surface.
3291 */
3292 if (pSurface->format == SVGA3D_BUFFER)
3293 {
3294 /* Upload the current data, if any. */
3295 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
3296 D3D11_SUBRESOURCE_DATA initialData;
3297 if (pMipLevel->pSurfaceData)
3298 {
3299 initialData.pSysMem = pMipLevel->pSurfaceData;
3300 initialData.SysMemPitch = pMipLevel->cbSurface;
3301 initialData.SysMemSlicePitch = pMipLevel->cbSurface;
3302
3303 pInitialData = &initialData;
3304 }
3305
3306 D3D11_BUFFER_DESC bd;
3307 RT_ZERO(bd);
3308 bd.ByteWidth = pMipLevel->cbSurface;
3309
3310 if (pSurface->f.surfaceFlags & (SVGA3D_SURFACE_STAGING_UPLOAD | SVGA3D_SURFACE_STAGING_DOWNLOAD))
3311 bd.Usage = D3D11_USAGE_STAGING;
3312 else if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_HINT_DYNAMIC)
3313 bd.Usage = D3D11_USAGE_DYNAMIC;
3314 else if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_HINT_STATIC)
3315 {
3316 /* Use D3D11_USAGE_DEFAULT instead of D3D11_USAGE_IMMUTABLE to let the guest the guest update
3317 * the buffer later.
3318 *
3319 * The guest issues SVGA_3D_CMD_INVALIDATE_GB_IMAGE followed by SVGA_3D_CMD_UPDATE_GB_IMAGE
3320 * when the data in SVGA3D_SURFACE_HINT_STATIC surface is updated.
3321 * D3D11_USAGE_IMMUTABLE would work if the device destroys the D3D buffer on INVALIDATE
3322 * and re-creates it in setupPipeline with initial data from the backing guest MOB.
3323 * Currently the device does not destroy the buffer on INVALIDATE. So just use D3D11_USAGE_DEFAULT.
3324 */
3325 bd.Usage = D3D11_USAGE_DEFAULT;
3326 }
3327 else if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_HINT_INDIRECT_UPDATE)
3328 bd.Usage = D3D11_USAGE_DEFAULT;
3329
3330 bd.BindFlags = dxBindFlags(pSurface->f.surfaceFlags);
3331
3332 if (bd.Usage == D3D11_USAGE_STAGING)
3333 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
3334 else if (bd.Usage == D3D11_USAGE_DYNAMIC)
3335 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
3336
3337 if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_DRAWINDIRECT_ARGS)
3338 bd.MiscFlags |= D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS;
3339 if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_BIND_RAW_VIEWS)
3340 bd.MiscFlags |= D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
3341 if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_BUFFER_STRUCTURED)
3342 bd.MiscFlags |= D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
3343 if (pSurface->f.surfaceFlags & SVGA3D_SURFACE_RESOURCE_CLAMP)
3344 bd.MiscFlags |= D3D11_RESOURCE_MISC_RESOURCE_CLAMP;
3345
3346 if (bd.MiscFlags & D3D11_RESOURCE_MISC_BUFFER_STRUCTURED)
3347 {
3348 SVGAOTableSurfaceEntry entrySurface;
3349 rc = vmsvgaR3OTableReadSurface(pThisCC->svga.pSvgaR3State, pSurface->id, &entrySurface);
3350 AssertRCReturn(rc, rc);
3351
3352 bd.StructureByteStride = entrySurface.bufferByteStride;
3353 }
3354
3355 hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.pBuffer);
3356 Assert(SUCCEEDED(hr));
3357#ifndef DX_COMMON_STAGING_BUFFER
3358 if (SUCCEEDED(hr))
3359 {
3360 /* Map-able Buffer. */
3361 bd.Usage = D3D11_USAGE_DYNAMIC;
3362 bd.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
3363 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
3364 hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->dynamic.pBuffer);
3365 Assert(SUCCEEDED(hr));
3366 }
3367
3368 if (SUCCEEDED(hr))
3369 {
3370 /* Staging texture. */
3371 bd.Usage = D3D11_USAGE_STAGING;
3372 bd.BindFlags = 0; /* No flags allowed. */
3373 bd.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
3374 hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->staging.pBuffer);
3375 Assert(SUCCEEDED(hr));
3376 }
3377#endif
3378 if (SUCCEEDED(hr))
3379 {
3380 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
3381 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
3382 }
3383 }
3384 else
3385 {
3386 /** @todo Texture. Currently vmsvga3dBackSurfaceCreateTexture is called for textures. */
3387 AssertFailed();
3388 hr = E_FAIL;
3389 }
3390
3391 if (SUCCEEDED(hr))
3392 {
3393 /*
3394 * Success.
3395 */
3396 pSurface->pBackendSurface = pBackendSurface;
3397 pSurface->idAssociatedContext = pDXContext->cid;
3398 return VINF_SUCCESS;
3399 }
3400
3401 /* Failure. */
3402 D3D_RELEASE(pBackendSurface->u.pResource);
3403 D3D_RELEASE(pBackendSurface->dynamic.pResource);
3404 D3D_RELEASE(pBackendSurface->staging.pResource);
3405 RTMemFree(pBackendSurface);
3406 return VERR_NO_MEMORY;
3407}
3408
3409
3410static int dxEnsureResource(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t sid,
3411 PVMSVGA3DSURFACE *ppSurface, ID3D11Resource **ppResource)
3412{
3413 /* Get corresponding resource for sid. Create the surface if does not yet exist. */
3414 PVMSVGA3DSURFACE pSurface;
3415 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
3416 AssertRCReturn(rc, rc);
3417
3418 if (pSurface->pBackendSurface == NULL)
3419 {
3420 /* Create the actual texture or buffer. */
3421 /** @todo One function to create all resources from surfaces. */
3422 if (pSurface->format != SVGA3D_BUFFER)
3423 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSurface);
3424 else
3425 rc = vmsvga3dBackSurfaceCreateResource(pThisCC, pDXContext, pSurface);
3426
3427 AssertRCReturn(rc, rc);
3428 LogFunc(("Created for sid = %u\n", sid));
3429 }
3430
3431 ID3D11Resource *pResource = dxResource(pThisCC->svga.p3dState, pSurface, pDXContext);
3432 AssertReturn(pResource, VERR_INVALID_STATE);
3433
3434 *ppSurface = pSurface;
3435 *ppResource = pResource;
3436 return VINF_SUCCESS;
3437}
3438
3439
3440#ifdef DX_COMMON_STAGING_BUFFER
3441static int dxStagingBufferRealloc(DXDEVICE *pDXDevice, uint32_t cbRequiredSize)
3442{
3443 AssertReturn(cbRequiredSize < SVGA3D_MAX_SURFACE_MEM_SIZE, VERR_INVALID_PARAMETER);
3444
3445 if (RT_LIKELY(cbRequiredSize <= pDXDevice->cbStagingBuffer))
3446 return VINF_SUCCESS;
3447
3448 D3D_RELEASE(pDXDevice->pStagingBuffer);
3449
3450 uint32_t const cbAlloc = RT_ALIGN_32(cbRequiredSize, _64K);
3451
3452 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
3453 D3D11_BUFFER_DESC bd;
3454 RT_ZERO(bd);
3455 bd.ByteWidth = cbAlloc;
3456 bd.Usage = D3D11_USAGE_STAGING;
3457 //bd.BindFlags = 0; /* No bind flags are allowed for staging resources. */
3458 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
3459
3460 int rc = VINF_SUCCESS;
3461 ID3D11Buffer *pBuffer;
3462 HRESULT hr = pDXDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBuffer);
3463 if (SUCCEEDED(hr))
3464 {
3465 pDXDevice->pStagingBuffer = pBuffer;
3466 pDXDevice->cbStagingBuffer = cbAlloc;
3467 }
3468 else
3469 {
3470 pDXDevice->cbStagingBuffer = 0;
3471 rc = VERR_NO_MEMORY;
3472 }
3473
3474 return rc;
3475}
3476#endif
3477
3478
3479static DECLCALLBACK(int) vmsvga3dBackInit(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC)
3480{
3481 RT_NOREF(pDevIns, pThis);
3482
3483 int rc;
3484#ifdef RT_OS_LINUX /** @todo Remove, this is currently needed for loading the X11 library in order to call XInitThreads(). */
3485 rc = glLdrInit(pDevIns);
3486 if (RT_FAILURE(rc))
3487 {
3488 LogRel(("VMSVGA3d: Error loading OpenGL library and resolving necessary functions: %Rrc\n", rc));
3489 return rc;
3490 }
3491#endif
3492
3493 PVMSVGA3DBACKEND pBackend = (PVMSVGA3DBACKEND)RTMemAllocZ(sizeof(VMSVGA3DBACKEND));
3494 AssertReturn(pBackend, VERR_NO_MEMORY);
3495 pThisCC->svga.p3dState->pBackend = pBackend;
3496
3497 rc = RTLdrLoadSystem(VBOX_D3D11_LIBRARY_NAME, /* fNoUnload = */ true, &pBackend->hD3D11);
3498 AssertRC(rc);
3499 if (RT_SUCCESS(rc))
3500 {
3501 rc = RTLdrGetSymbol(pBackend->hD3D11, "D3D11CreateDevice", (void **)&pBackend->pfnD3D11CreateDevice);
3502 AssertRC(rc);
3503 }
3504
3505 if (RT_SUCCESS(rc))
3506 {
3507 /* Failure to load the shader disassembler is ignored. */
3508 int rc2 = RTLdrLoadSystem("D3DCompiler_47", /* fNoUnload = */ true, &pBackend->hD3DCompiler);
3509 if (RT_SUCCESS(rc2))
3510 rc2 = RTLdrGetSymbol(pBackend->hD3DCompiler, "D3DDisassemble", (void **)&pBackend->pfnD3DDisassemble);
3511 Log6Func(("Load D3DDisassemble: %Rrc\n", rc2));
3512 }
3513
3514#if !defined(RT_OS_WINDOWS) || defined(DX_FORCE_SINGLE_DEVICE)
3515 pBackend->fSingleDevice = true;
3516#endif
3517
3518 LogRelMax(1, ("VMSVGA: Single DX device mode: %s\n", pBackend->fSingleDevice ? "enabled" : "disabled"));
3519
3520 vmsvga3dDXInitContextMobData(&pBackend->svgaDXContext);
3521//DEBUG_BREAKPOINT_TEST();
3522 return rc;
3523}
3524
3525
3526static DECLCALLBACK(int) vmsvga3dBackPowerOn(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC)
3527{
3528 RT_NOREF(pDevIns, pThis);
3529
3530 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3531 AssertReturn(pState, VERR_INVALID_STATE);
3532
3533 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3534 AssertReturn(pBackend, VERR_INVALID_STATE);
3535
3536 int rc = dxDeviceCreate(pBackend, &pBackend->dxDevice);
3537 if (RT_SUCCESS(rc))
3538 {
3539 IDXGIAdapter *pAdapter = NULL;
3540 HRESULT hr = pBackend->dxDevice.pDxgiFactory->EnumAdapters(0, &pAdapter);
3541 if (SUCCEEDED(hr))
3542 {
3543 DXGI_ADAPTER_DESC desc;
3544 hr = pAdapter->GetDesc(&desc);
3545 if (SUCCEEDED(hr))
3546 {
3547 pBackend->VendorId = desc.VendorId;
3548 pBackend->DeviceId = desc.DeviceId;
3549
3550 char sz[RT_ELEMENTS(desc.Description)];
3551 for (unsigned i = 0; i < RT_ELEMENTS(desc.Description); ++i)
3552 sz[i] = (char)desc.Description[i];
3553 LogRelMax(1, ("VMSVGA: Adapter %04x:%04x [%s]\n", pBackend->VendorId, pBackend->DeviceId, sz));
3554 }
3555
3556 pAdapter->Release();
3557 }
3558
3559 if (pBackend->dxDevice.pVideoDevice)
3560 dxLogRelVideoCaps(pBackend->dxDevice.pVideoDevice);
3561
3562 if (!pThis->svga.fVMSVGA3dMSAA)
3563 pBackend->dxDevice.MultisampleCountMask = 0;
3564 }
3565 return rc;
3566}
3567
3568
3569static DECLCALLBACK(int) vmsvga3dBackReset(PVGASTATECC pThisCC)
3570{
3571 RT_NOREF(pThisCC);
3572 return VINF_SUCCESS;
3573}
3574
3575
3576static DECLCALLBACK(int) vmsvga3dBackTerminate(PVGASTATECC pThisCC)
3577{
3578 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3579 AssertReturn(pState, VERR_INVALID_STATE);
3580
3581 if (pState->pBackend)
3582 dxDeviceDestroy(pState->pBackend, &pState->pBackend->dxDevice);
3583
3584 return VINF_SUCCESS;
3585}
3586
3587
3588/** @todo Such structures must be in VBoxVideo3D.h */
3589typedef struct VBOX3DNOTIFYDEFINESCREEN
3590{
3591 VBOX3DNOTIFY Core;
3592 uint32_t cWidth;
3593 uint32_t cHeight;
3594 int32_t xRoot;
3595 int32_t yRoot;
3596 uint32_t fPrimary;
3597 uint32_t cDpi;
3598} VBOX3DNOTIFYDEFINESCREEN;
3599
3600
3601static int vmsvga3dDrvNotifyDefineScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
3602{
3603 VBOX3DNOTIFYDEFINESCREEN n;
3604 n.Core.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_CREATED;
3605 n.Core.iDisplay = pScreen->idScreen;
3606 n.Core.u32Reserved = 0;
3607 n.Core.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
3608 RT_ZERO(n.Core.au8Data);
3609 n.cWidth = pScreen->cWidth;
3610 n.cHeight = pScreen->cHeight;
3611 n.xRoot = pScreen->xOrigin;
3612 n.yRoot = pScreen->yOrigin;
3613 n.fPrimary = RT_BOOL(pScreen->fuScreen & SVGA_SCREEN_IS_PRIMARY);
3614 n.cDpi = pScreen->cDpi;
3615
3616 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n.Core);
3617}
3618
3619
3620static int vmsvga3dDrvNotifyDestroyScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
3621{
3622 VBOX3DNOTIFY n;
3623 n.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_DESTROYED;
3624 n.iDisplay = pScreen->idScreen;
3625 n.u32Reserved = 0;
3626 n.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
3627 RT_ZERO(n.au8Data);
3628
3629 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n);
3630}
3631
3632
3633static int vmsvga3dDrvNotifyBindSurface(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, HANDLE hSharedSurface)
3634{
3635 VBOX3DNOTIFY n;
3636 n.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_BIND_SURFACE;
3637 n.iDisplay = pScreen->idScreen;
3638 n.u32Reserved = 0;
3639 n.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
3640 *(uint64_t *)&n.au8Data[0] = (uint64_t)hSharedSurface;
3641
3642 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n);
3643}
3644
3645
3646typedef struct VBOX3DNOTIFYUPDATE
3647{
3648 VBOX3DNOTIFY Core;
3649 uint32_t x;
3650 uint32_t y;
3651 uint32_t w;
3652 uint32_t h;
3653} VBOX3DNOTIFYUPDATE;
3654
3655
3656static int vmsvga3dDrvNotifyUpdate(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen,
3657 uint32_t x, uint32_t y, uint32_t w, uint32_t h)
3658{
3659 VBOX3DNOTIFYUPDATE n;
3660 n.Core.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_UPDATE_END;
3661 n.Core.iDisplay = pScreen->idScreen;
3662 n.Core.u32Reserved = 0;
3663 n.Core.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
3664 RT_ZERO(n.Core.au8Data);
3665 n.x = x;
3666 n.y = y;
3667 n.w = w;
3668 n.h = h;
3669
3670 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n.Core);
3671}
3672
3673static int vmsvga3dHwScreenCreate(PVMSVGA3DSTATE pState, uint32_t cWidth, uint32_t cHeight, VMSVGAHWSCREEN *p)
3674{
3675 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3676
3677 DXDEVICE *pDXDevice = &pBackend->dxDevice;
3678 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
3679
3680 D3D11_TEXTURE2D_DESC td;
3681 RT_ZERO(td);
3682 td.Width = cWidth;
3683 td.Height = cHeight;
3684 td.MipLevels = 1;
3685 td.ArraySize = 1;
3686 td.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
3687 td.SampleDesc.Count = 1;
3688 td.SampleDesc.Quality = 0;
3689 td.Usage = D3D11_USAGE_DEFAULT;
3690 td.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
3691 td.CPUAccessFlags = 0;
3692 td.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
3693
3694 HRESULT hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &p->pTexture);
3695 if (SUCCEEDED(hr))
3696 {
3697 /* Get the shared handle. */
3698 hr = p->pTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&p->pDxgiResource);
3699 if (SUCCEEDED(hr))
3700 {
3701 hr = p->pDxgiResource->GetSharedHandle(&p->SharedHandle);
3702 if (SUCCEEDED(hr))
3703 hr = p->pTexture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)&p->pDXGIKeyedMutex);
3704 }
3705 }
3706
3707 if (SUCCEEDED(hr))
3708 return VINF_SUCCESS;
3709
3710 AssertFailed();
3711 return VERR_NOT_SUPPORTED;
3712}
3713
3714
3715static void vmsvga3dHwScreenDestroy(PVMSVGA3DSTATE pState, VMSVGAHWSCREEN *p)
3716{
3717 RT_NOREF(pState);
3718 D3D_RELEASE(p->pDXGIKeyedMutex);
3719 D3D_RELEASE(p->pDxgiResource);
3720 D3D_RELEASE(p->pTexture);
3721 p->SharedHandle = 0;
3722 p->sidScreenTarget = SVGA_ID_INVALID;
3723}
3724
3725
3726static DECLCALLBACK(int) vmsvga3dBackDefineScreen(PVGASTATE pThis, PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
3727{
3728 RT_NOREF(pThis, pThisCC, pScreen);
3729
3730 LogRel4(("VMSVGA: vmsvga3dBackDefineScreen: screen %u\n", pScreen->idScreen));
3731
3732 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3733 AssertReturn(pState, VERR_INVALID_STATE);
3734
3735 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3736 AssertReturn(pBackend, VERR_INVALID_STATE);
3737
3738 Assert(pScreen->pHwScreen == NULL);
3739
3740 VMSVGAHWSCREEN *p = (VMSVGAHWSCREEN *)RTMemAllocZ(sizeof(VMSVGAHWSCREEN));
3741 AssertPtrReturn(p, VERR_NO_MEMORY);
3742
3743 p->sidScreenTarget = SVGA_ID_INVALID;
3744
3745 int rc = vmsvga3dDrvNotifyDefineScreen(pThisCC, pScreen);
3746 if (RT_SUCCESS(rc))
3747 {
3748 /* The frontend supports the screen. Create the actual resource. */
3749 rc = vmsvga3dHwScreenCreate(pState, pScreen->cWidth, pScreen->cHeight, p);
3750 if (RT_SUCCESS(rc))
3751 LogRel4(("VMSVGA: vmsvga3dBackDefineScreen: created\n"));
3752 }
3753
3754 if (RT_SUCCESS(rc))
3755 {
3756 LogRel(("VMSVGA: Using HW accelerated screen %u\n", pScreen->idScreen));
3757 pScreen->pHwScreen = p;
3758 }
3759 else
3760 {
3761 LogRel4(("VMSVGA: vmsvga3dBackDefineScreen: %Rrc\n", rc));
3762 vmsvga3dHwScreenDestroy(pState, p);
3763 RTMemFree(p);
3764 }
3765
3766 return rc;
3767}
3768
3769
3770static DECLCALLBACK(int) vmsvga3dBackDestroyScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
3771{
3772 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3773 AssertReturn(pState, VERR_INVALID_STATE);
3774
3775 vmsvga3dDrvNotifyDestroyScreen(pThisCC, pScreen);
3776
3777 if (pScreen->pHwScreen)
3778 {
3779 vmsvga3dHwScreenDestroy(pState, pScreen->pHwScreen);
3780 RTMemFree(pScreen->pHwScreen);
3781 pScreen->pHwScreen = NULL;
3782 }
3783
3784 return VINF_SUCCESS;
3785}
3786
3787
3788static DECLCALLBACK(int) vmsvga3dBackSurfaceBlitToScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen,
3789 SVGASignedRect destRect, SVGA3dSurfaceImageId srcImage,
3790 SVGASignedRect srcRect, uint32_t cRects, SVGASignedRect *paRects)
3791{
3792 RT_NOREF(pThisCC, pScreen, destRect, srcImage, srcRect, cRects, paRects);
3793
3794 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3795 AssertReturn(pState, VERR_INVALID_STATE);
3796
3797 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3798 AssertReturn(pBackend, VERR_INVALID_STATE);
3799
3800 VMSVGAHWSCREEN *p = pScreen->pHwScreen;
3801 AssertReturn(p, VERR_NOT_SUPPORTED);
3802
3803 PVMSVGA3DSURFACE pSurface;
3804 int rc = vmsvga3dSurfaceFromSid(pState, srcImage.sid, &pSurface);
3805 AssertRCReturn(rc, rc);
3806
3807 /** @todo Implement. */
3808 AssertFailed();
3809 return VERR_NOT_IMPLEMENTED;
3810}
3811
3812
3813static DECLCALLBACK(int) vmsvga3dBackSurfaceMap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, SVGA3dBox const *pBox,
3814 VMSVGA3D_SURFACE_MAP enmMapType, VMSVGA3D_MAPPED_SURFACE *pMap)
3815{
3816 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3817 AssertReturn(pState, VERR_INVALID_STATE);
3818
3819 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3820 AssertReturn(pBackend, VERR_INVALID_STATE);
3821
3822 PVMSVGA3DSURFACE pSurface;
3823 int rc = vmsvga3dSurfaceFromSid(pState, pImage->sid, &pSurface);
3824 AssertRCReturn(rc, rc);
3825
3826 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
3827 AssertPtrReturn(pBackendSurface, VERR_INVALID_STATE);
3828
3829 PVMSVGA3DMIPMAPLEVEL pMipLevel;
3830 rc = vmsvga3dMipmapLevel(pSurface, pImage->face, pImage->mipmap, &pMipLevel);
3831 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
3832
3833 /* A surface is always mapped by the DX context which has created the surface. */
3834 DXDEVICE *pDevice = dxDeviceFromCid(pSurface->idAssociatedContext, pState);
3835 AssertReturn(pDevice && pDevice->pDevice, VERR_INVALID_STATE);
3836
3837 SVGA3dBox clipBox;
3838 if (pBox)
3839 {
3840 clipBox = *pBox;
3841 vmsvgaR3ClipBox(&pMipLevel->mipmapSize, &clipBox);
3842 ASSERT_GUEST_RETURN(clipBox.w && clipBox.h && clipBox.d, VERR_INVALID_PARAMETER);
3843 }
3844 else
3845 {
3846 clipBox.x = 0;
3847 clipBox.y = 0;
3848 clipBox.z = 0;
3849 clipBox.w = pMipLevel->mipmapSize.width;
3850 clipBox.h = pMipLevel->mipmapSize.height;
3851 clipBox.d = pMipLevel->mipmapSize.depth;
3852 }
3853
3854 D3D11_MAP d3d11MapType;
3855 switch (enmMapType)
3856 {
3857 case VMSVGA3D_SURFACE_MAP_READ: d3d11MapType = D3D11_MAP_READ; break;
3858 case VMSVGA3D_SURFACE_MAP_WRITE: d3d11MapType = D3D11_MAP_WRITE; break;
3859 case VMSVGA3D_SURFACE_MAP_READ_WRITE: d3d11MapType = D3D11_MAP_READ_WRITE; break;
3860 case VMSVGA3D_SURFACE_MAP_WRITE_DISCARD: d3d11MapType = D3D11_MAP_WRITE_DISCARD; break;
3861 default:
3862 AssertFailed();
3863 return VERR_INVALID_PARAMETER;
3864 }
3865
3866 D3D11_MAPPED_SUBRESOURCE mappedResource;
3867 RT_ZERO(mappedResource);
3868
3869 if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_1D
3870 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
3871 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_CUBE
3872 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3873 {
3874 dxSurfaceWait(pState, pSurface, pSurface->idAssociatedContext);
3875
3876 ID3D11Resource *pMappedResource;
3877 if (enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3878 {
3879 pMappedResource = pBackendSurface->staging.pResource;
3880
3881 /* Copy the texture content to the staging texture.
3882 * The requested miplevel of the texture is copied to the miplevel 0 of the staging texture,
3883 * because the staging (and dynamic) structures do not have miplevels.
3884 * Always copy entire miplevel so all Dst are zero and pSrcBox is NULL, as D3D11 requires.
3885 */
3886 ID3D11Resource *pDstResource = pMappedResource;
3887 UINT DstSubresource = 0;
3888 UINT DstX = 0;
3889 UINT DstY = 0;
3890 UINT DstZ = 0;
3891 ID3D11Resource *pSrcResource = pBackendSurface->u.pResource;
3892 UINT SrcSubresource = D3D11CalcSubresource(pImage->mipmap, pImage->face, pSurface->cLevels);
3893 D3D11_BOX *pSrcBox = NULL;
3894 //D3D11_BOX SrcBox;
3895 //SrcBox.left = 0;
3896 //SrcBox.top = 0;
3897 //SrcBox.front = 0;
3898 //SrcBox.right = pMipLevel->mipmapSize.width;
3899 //SrcBox.bottom = pMipLevel->mipmapSize.height;
3900 //SrcBox.back = pMipLevel->mipmapSize.depth;
3901 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3902 pSrcResource, SrcSubresource, pSrcBox);
3903 }
3904 else if (enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
3905 pMappedResource = pBackendSurface->staging.pResource;
3906 else
3907 pMappedResource = pBackendSurface->dynamic.pResource;
3908
3909 UINT const Subresource = 0; /* Dynamic or staging textures have one subresource. */
3910 HRESULT hr = pDevice->pImmediateContext->Map(pMappedResource, Subresource,
3911 d3d11MapType, /* MapFlags = */ 0, &mappedResource);
3912 if (SUCCEEDED(hr))
3913 vmsvga3dSurfaceMapInit(pMap, enmMapType, &clipBox, pSurface,
3914 mappedResource.pData, mappedResource.RowPitch, mappedResource.DepthPitch);
3915 else
3916 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
3917 }
3918 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
3919 {
3920#ifdef DX_COMMON_STAGING_BUFFER
3921 /* Map the staging buffer. */
3922 rc = dxStagingBufferRealloc(pDevice, pMipLevel->cbSurface);
3923 if (RT_SUCCESS(rc))
3924 {
3925 /* The staging buffer does not allow D3D11_MAP_WRITE_DISCARD, so replace it. */
3926 if (d3d11MapType == D3D11_MAP_WRITE_DISCARD)
3927 d3d11MapType = D3D11_MAP_WRITE;
3928
3929 if (enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3930 {
3931 /* Copy from the buffer to the staging buffer. */
3932 ID3D11Resource *pDstResource = pDevice->pStagingBuffer;
3933 UINT DstSubresource = 0;
3934 UINT DstX = clipBox.x;
3935 UINT DstY = clipBox.y;
3936 UINT DstZ = clipBox.z;
3937 ID3D11Resource *pSrcResource = pBackendSurface->u.pResource;
3938 UINT SrcSubresource = 0;
3939 D3D11_BOX SrcBox;
3940 SrcBox.left = clipBox.x;
3941 SrcBox.top = clipBox.y;
3942 SrcBox.front = clipBox.z;
3943 SrcBox.right = clipBox.w;
3944 SrcBox.bottom = clipBox.h;
3945 SrcBox.back = clipBox.d;
3946 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3947 pSrcResource, SrcSubresource, &SrcBox);
3948 }
3949
3950 UINT const Subresource = 0; /* Buffers have only one subresource. */
3951 HRESULT hr = pDevice->pImmediateContext->Map(pDevice->pStagingBuffer, Subresource,
3952 d3d11MapType, /* MapFlags = */ 0, &mappedResource);
3953 if (SUCCEEDED(hr))
3954 vmsvga3dSurfaceMapInit(pMap, enmMapType, &clipBox, pSurface,
3955 mappedResource.pData, mappedResource.RowPitch, mappedResource.DepthPitch);
3956 else
3957 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
3958 }
3959#else
3960 ID3D11Resource *pMappedResource;
3961 if (enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3962 {
3963 pMappedResource = pBackendSurface->staging.pResource;
3964
3965 /* Copy the resource content to the staging resource. */
3966 ID3D11Resource *pDstResource = pMappedResource;
3967 UINT DstSubresource = 0;
3968 UINT DstX = clipBox.x;
3969 UINT DstY = clipBox.y;
3970 UINT DstZ = clipBox.z;
3971 ID3D11Resource *pSrcResource = pBackendSurface->u.pResource;
3972 UINT SrcSubresource = 0;
3973 D3D11_BOX SrcBox;
3974 SrcBox.left = clipBox.x;
3975 SrcBox.top = clipBox.y;
3976 SrcBox.front = clipBox.z;
3977 SrcBox.right = clipBox.w;
3978 SrcBox.bottom = clipBox.h;
3979 SrcBox.back = clipBox.d;
3980 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3981 pSrcResource, SrcSubresource, &SrcBox);
3982 }
3983 else if (enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
3984 pMappedResource = pBackendSurface->staging.pResource;
3985 else
3986 pMappedResource = pBackendSurface->dynamic.pResource;
3987
3988 UINT const Subresource = 0; /* Dynamic or staging textures have one subresource. */
3989 HRESULT hr = pDevice->pImmediateContext->Map(pMappedResource, Subresource,
3990 d3d11MapType, /* MapFlags = */ 0, &mappedResource);
3991 if (SUCCEEDED(hr))
3992 vmsvga3dSurfaceMapInit(pMap, enmMapType, &clipBox, pSurface,
3993 mappedResource.pData, mappedResource.RowPitch, mappedResource.DepthPitch);
3994 else
3995 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
3996#endif
3997 }
3998 else
3999 {
4000 // UINT D3D11CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT MipLevels);
4001 /** @todo Implement. */
4002 AssertFailed();
4003 rc = VERR_NOT_IMPLEMENTED;
4004 }
4005
4006 return rc;
4007}
4008
4009
4010static DECLCALLBACK(int) vmsvga3dBackSurfaceUnmap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, VMSVGA3D_MAPPED_SURFACE *pMap, bool fWritten)
4011{
4012 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4013 AssertReturn(pState, VERR_INVALID_STATE);
4014
4015 PVMSVGA3DBACKEND pBackend = pState->pBackend;
4016 AssertReturn(pBackend, VERR_INVALID_STATE);
4017
4018 PVMSVGA3DSURFACE pSurface;
4019 int rc = vmsvga3dSurfaceFromSid(pState, pImage->sid, &pSurface);
4020 AssertRCReturn(rc, rc);
4021
4022 /* The called should not use the function for system memory surfaces. */
4023 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
4024 AssertReturn(pBackendSurface, VERR_INVALID_PARAMETER);
4025
4026 PVMSVGA3DMIPMAPLEVEL pMipLevel;
4027 rc = vmsvga3dMipmapLevel(pSurface, pImage->face, pImage->mipmap, &pMipLevel);
4028 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
4029
4030 /* A surface is always mapped by the DX context which has created the surface. */
4031 DXDEVICE *pDevice = dxDeviceFromCid(pSurface->idAssociatedContext, pState);
4032 AssertReturn(pDevice && pDevice->pDevice, VERR_INVALID_STATE);
4033
4034 if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_1D
4035 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
4036 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_CUBE
4037 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
4038 {
4039 ID3D11Resource *pMappedResource;
4040 if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ)
4041 pMappedResource = pBackendSurface->staging.pResource;
4042 else if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
4043 pMappedResource = pBackendSurface->staging.pResource;
4044 else
4045 pMappedResource = pBackendSurface->dynamic.pResource;
4046
4047 UINT const Subresource = 0; /* Staging or dynamic textures have one subresource. */
4048 pDevice->pImmediateContext->Unmap(pMappedResource, Subresource);
4049
4050 if ( fWritten
4051 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
4052 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
4053 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
4054 {
4055 /* If entire resource must be copied then use pSrcBox = NULL and dst point (0,0,0)
4056 * Because DX11 insists on this for some resource types, for example DEPTH_STENCIL resources.
4057 */
4058 uint32_t const cWidth0 = pSurface->paMipmapLevels[0].mipmapSize.width;
4059 uint32_t const cHeight0 = pSurface->paMipmapLevels[0].mipmapSize.height;
4060 uint32_t const cDepth0 = pSurface->paMipmapLevels[0].mipmapSize.depth;
4061 /** @todo Entire subresource is always mapped. So find a way to copy it back, important for DEPTH_STENCIL mipmaps. */
4062 bool const fEntireResource = pMap->box.x == 0 && pMap->box.y == 0 && pMap->box.z == 0
4063 && pMap->box.w == cWidth0 && pMap->box.h == cHeight0 && pMap->box.d == cDepth0;
4064
4065 ID3D11Resource *pDstResource = pBackendSurface->u.pResource;
4066 UINT DstSubresource = D3D11CalcSubresource(pImage->mipmap, pImage->face, pSurface->cLevels);
4067 UINT DstX = (pMap->box.x / pSurface->cxBlock) * pSurface->cxBlock;
4068 UINT DstY = (pMap->box.y / pSurface->cyBlock) * pSurface->cyBlock;
4069 UINT DstZ = pMap->box.z;
4070 ID3D11Resource *pSrcResource = pMappedResource;
4071 UINT SrcSubresource = Subresource;
4072 D3D11_BOX *pSrcBox;
4073 D3D11_BOX SrcBox;
4074 if (fEntireResource)
4075 pSrcBox = NULL;
4076 else
4077 {
4078 uint32_t const cxBlocks = (pMap->box.w + pSurface->cxBlock - 1) / pSurface->cxBlock;
4079 uint32_t const cyBlocks = (pMap->box.h + pSurface->cyBlock - 1) / pSurface->cyBlock;
4080
4081 SrcBox.left = DstX;
4082 SrcBox.top = DstY;
4083 SrcBox.front = DstZ;
4084 SrcBox.right = DstX + cxBlocks * pSurface->cxBlock;
4085 SrcBox.bottom = DstY + cyBlocks * pSurface->cyBlock;
4086 SrcBox.back = DstZ + pMap->box.d;
4087 pSrcBox = &SrcBox;
4088 }
4089
4090 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
4091 pSrcResource, SrcSubresource, pSrcBox);
4092
4093 pBackendSurface->cidDrawing = pSurface->idAssociatedContext;
4094 }
4095 }
4096 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
4097 {
4098 Log4(("Unmap buffer sid = %u:\n%.*Rhxd\n", pSurface->id, pMap->cbRow, pMap->pvData));
4099
4100#ifdef DX_COMMON_STAGING_BUFFER
4101 /* Unmap the staging buffer. */
4102 UINT const Subresource = 0; /* Buffers have only one subresource. */
4103 pDevice->pImmediateContext->Unmap(pDevice->pStagingBuffer, Subresource);
4104
4105 /* Copy from the staging buffer to the actual buffer */
4106 if ( fWritten
4107 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
4108 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
4109 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
4110 {
4111 ID3D11Resource *pDstResource = pBackendSurface->u.pResource;
4112 UINT DstSubresource = 0;
4113 UINT DstX = (pMap->box.x / pSurface->cxBlock) * pSurface->cxBlock;
4114 UINT DstY = (pMap->box.y / pSurface->cyBlock) * pSurface->cyBlock;
4115 UINT DstZ = pMap->box.z;
4116 ID3D11Resource *pSrcResource = pDevice->pStagingBuffer;
4117 UINT SrcSubresource = 0;
4118 D3D11_BOX SrcBox;
4119
4120 uint32_t const cxBlocks = (pMap->box.w + pSurface->cxBlock - 1) / pSurface->cxBlock;
4121 uint32_t const cyBlocks = (pMap->box.h + pSurface->cyBlock - 1) / pSurface->cyBlock;
4122
4123 SrcBox.left = DstX;
4124 SrcBox.top = DstY;
4125 SrcBox.front = DstZ;
4126 SrcBox.right = DstX + cxBlocks * pSurface->cxBlock;
4127 SrcBox.bottom = DstY + cyBlocks * pSurface->cyBlock;
4128 SrcBox.back = DstZ + pMap->box.d;
4129
4130 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
4131 pSrcResource, SrcSubresource, &SrcBox);
4132 }
4133#else
4134 ID3D11Resource *pMappedResource;
4135 if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ)
4136 pMappedResource = pBackendSurface->staging.pResource;
4137 else if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
4138 pMappedResource = pBackendSurface->staging.pResource;
4139 else
4140 pMappedResource = pBackendSurface->dynamic.pResource;
4141
4142 UINT const Subresource = 0; /* Staging or dynamic textures have one subresource. */
4143 pDevice->pImmediateContext->Unmap(pMappedResource, Subresource);
4144
4145 if ( fWritten
4146 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
4147 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
4148 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
4149 {
4150 ID3D11Resource *pDstResource = pBackendSurface->u.pResource;
4151 UINT DstSubresource = 0;
4152 UINT DstX = pMap->box.x;
4153 UINT DstY = pMap->box.y;
4154 UINT DstZ = pMap->box.z;
4155 ID3D11Resource *pSrcResource = pMappedResource;
4156 UINT SrcSubresource = 0;
4157 D3D11_BOX SrcBox;
4158 SrcBox.left = DstX;
4159 SrcBox.top = DstY;
4160 SrcBox.front = DstZ;
4161 SrcBox.right = DstX + pMap->box.w;
4162 SrcBox.bottom = DstY + pMap->box.h;
4163 SrcBox.back = DstZ + pMap->box.d;
4164 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
4165 pSrcResource, SrcSubresource, &SrcBox);
4166
4167 pBackendSurface->cidDrawing = pSurface->idAssociatedContext;
4168 }
4169#endif
4170 }
4171 else
4172 {
4173 AssertFailed();
4174 rc = VERR_NOT_IMPLEMENTED;
4175 }
4176
4177 return rc;
4178}
4179
4180
4181static DECLCALLBACK(int) vmsvga3dScreenTargetBind(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, uint32_t sid)
4182{
4183 int rc = VINF_SUCCESS;
4184
4185 PVMSVGA3DSURFACE pSurface;
4186 if (sid != SVGA_ID_INVALID)
4187 {
4188 /* Create the surface if does not yet exist. */
4189 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4190 AssertReturn(pState, VERR_INVALID_STATE);
4191
4192 rc = vmsvga3dSurfaceFromSid(pState, sid, &pSurface);
4193 AssertRCReturn(rc, rc);
4194
4195 if (!VMSVGA3DSURFACE_HAS_HW_SURFACE(pSurface))
4196 {
4197 /* Create the actual texture. */
4198 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, NULL, pSurface);
4199 AssertRCReturn(rc, rc);
4200 }
4201 }
4202 else
4203 pSurface = NULL;
4204
4205 /* Notify the HW accelerated screen if it is used. */
4206 VMSVGAHWSCREEN *pHwScreen = pScreen->pHwScreen;
4207 if (!pHwScreen)
4208 return VINF_SUCCESS;
4209
4210 /* Same surface -> do nothing. */
4211 if (pHwScreen->sidScreenTarget == sid)
4212 return VINF_SUCCESS;
4213
4214 if (sid != SVGA_ID_INVALID)
4215 {
4216 AssertReturn( pSurface->pBackendSurface
4217 && pSurface->pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
4218 && RT_BOOL(pSurface->f.surfaceFlags & SVGA3D_SURFACE_SCREENTARGET), VERR_INVALID_PARAMETER);
4219
4220 HANDLE const hSharedSurface = pHwScreen->SharedHandle;
4221 rc = vmsvga3dDrvNotifyBindSurface(pThisCC, pScreen, hSharedSurface);
4222 }
4223
4224 if (RT_SUCCESS(rc))
4225 {
4226 pHwScreen->sidScreenTarget = sid;
4227 }
4228
4229 return rc;
4230}
4231
4232
4233static DECLCALLBACK(int) vmsvga3dScreenTargetUpdate(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, SVGA3dRect const *pRect)
4234{
4235 VMSVGAHWSCREEN *pHwScreen = pScreen->pHwScreen;
4236 AssertReturn(pHwScreen, VERR_NOT_SUPPORTED);
4237
4238 if (pHwScreen->sidScreenTarget == SVGA_ID_INVALID)
4239 return VINF_SUCCESS; /* No surface bound. */
4240
4241 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4242 AssertReturn(pState, VERR_INVALID_STATE);
4243
4244 PVMSVGA3DBACKEND pBackend = pState->pBackend;
4245 AssertReturn(pBackend, VERR_INVALID_STATE);
4246
4247 PVMSVGA3DSURFACE pSurface;
4248 int rc = vmsvga3dSurfaceFromSid(pState, pHwScreen->sidScreenTarget, &pSurface);
4249 AssertRCReturn(rc, rc);
4250
4251 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
4252 AssertReturn( pBackendSurface
4253 && pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
4254 && RT_BOOL(pSurface->f.surfaceFlags & SVGA3D_SURFACE_SCREENTARGET),
4255 VERR_INVALID_PARAMETER);
4256
4257 SVGA3dRect boundRect;
4258 boundRect.x = 0;
4259 boundRect.y = 0;
4260 boundRect.w = pSurface->paMipmapLevels[0].mipmapSize.width;
4261 boundRect.h = pSurface->paMipmapLevels[0].mipmapSize.height;
4262 SVGA3dRect clipRect = *pRect;
4263 vmsvgaR3Clip3dRect(&boundRect, &clipRect);
4264 ASSERT_GUEST_RETURN(clipRect.w && clipRect.h, VERR_INVALID_PARAMETER);
4265
4266 /* Wait for the surface to finish drawing. */
4267 dxSurfaceWait(pState, pSurface, DX_CID_BACKEND);
4268
4269 /* Copy the screen texture to the shared surface. */
4270 DWORD result = pHwScreen->pDXGIKeyedMutex->AcquireSync(0, 10000);
4271 if (result == S_OK)
4272 {
4273 pBackend->dxDevice.pImmediateContext->CopyResource(pHwScreen->pTexture, pBackendSurface->u.pTexture2D);
4274
4275 dxDeviceFlush(&pBackend->dxDevice);
4276
4277 result = pHwScreen->pDXGIKeyedMutex->ReleaseSync(1);
4278 }
4279 else
4280 AssertFailed();
4281
4282 rc = vmsvga3dDrvNotifyUpdate(pThisCC, pScreen, pRect->x, pRect->y, pRect->w, pRect->h);
4283 return rc;
4284}
4285
4286
4287/*
4288 *
4289 * 3D interface.
4290 *
4291 */
4292
4293static DECLCALLBACK(int) vmsvga3dBackQueryCaps(PVGASTATECC pThisCC, SVGA3dDevCapIndex idx3dCaps, uint32_t *pu32Val)
4294{
4295 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4296 AssertReturn(pState, VERR_INVALID_STATE);
4297
4298 int rc = VINF_SUCCESS;
4299
4300 *pu32Val = 0;
4301
4302 if (idx3dCaps > SVGA3D_DEVCAP_MAX)
4303 {
4304 LogRelMax(16, ("VMSVGA: unsupported SVGA3D_DEVCAP %d\n", idx3dCaps));
4305 return VERR_NOT_SUPPORTED;
4306 }
4307
4308 D3D_FEATURE_LEVEL const FeatureLevel = pState->pBackend->dxDevice.FeatureLevel;
4309
4310 /* Most values are taken from:
4311 * https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-intro
4312 *
4313 * Shader values are from
4314 * https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-models
4315 */
4316
4317 switch (idx3dCaps)
4318 {
4319 case SVGA3D_DEVCAP_3D:
4320 *pu32Val = VBSVGA3D_CAP_3D;
4321 if (pState->pBackend->dxDevice.pVideoDevice)
4322 *pu32Val |= VBSVGA3D_CAP_VIDEO;
4323 break;
4324
4325 case SVGA3D_DEVCAP_MAX_LIGHTS:
4326 *pu32Val = SVGA3D_NUM_LIGHTS; /* VGPU9. Not applicable to DX11. */
4327 break;
4328
4329 case SVGA3D_DEVCAP_MAX_TEXTURES:
4330 *pu32Val = SVGA3D_NUM_TEXTURE_UNITS; /* VGPU9. Not applicable to DX11. */
4331 break;
4332
4333 case SVGA3D_DEVCAP_MAX_CLIP_PLANES:
4334 *pu32Val = SVGA3D_NUM_CLIPPLANES;
4335 break;
4336
4337 case SVGA3D_DEVCAP_VERTEX_SHADER_VERSION:
4338 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4339 *pu32Val = SVGA3DVSVERSION_40;
4340 else
4341 *pu32Val = SVGA3DVSVERSION_30;
4342 break;
4343
4344 case SVGA3D_DEVCAP_VERTEX_SHADER:
4345 *pu32Val = 1;
4346 break;
4347
4348 case SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION:
4349 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4350 *pu32Val = SVGA3DPSVERSION_40;
4351 else
4352 *pu32Val = SVGA3DPSVERSION_30;
4353 break;
4354
4355 case SVGA3D_DEVCAP_FRAGMENT_SHADER:
4356 *pu32Val = 1;
4357 break;
4358
4359 case SVGA3D_DEVCAP_MAX_RENDER_TARGETS:
4360 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4361 *pu32Val = 8;
4362 else
4363 *pu32Val = 4;
4364 break;
4365
4366 case SVGA3D_DEVCAP_S23E8_TEXTURES:
4367 case SVGA3D_DEVCAP_S10E5_TEXTURES:
4368 /* Must be obsolete by now; surface format caps specify the same thing. */
4369 break;
4370
4371 case SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND:
4372 /* Obsolete */
4373 break;
4374
4375 /*
4376 * 2. The BUFFER_FORMAT capabilities are deprecated, and they always
4377 * return TRUE. Even on physical hardware that does not support
4378 * these formats natively, the SVGA3D device will provide an emulation
4379 * which should be invisible to the guest OS.
4380 */
4381 case SVGA3D_DEVCAP_D16_BUFFER_FORMAT:
4382 case SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT:
4383 case SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT:
4384 *pu32Val = 1;
4385 break;
4386
4387 case SVGA3D_DEVCAP_QUERY_TYPES:
4388 /* Obsolete */
4389 break;
4390
4391 case SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING:
4392 /* Obsolete */
4393 break;
4394
4395 case SVGA3D_DEVCAP_MAX_POINT_SIZE:
4396 AssertCompile(sizeof(uint32_t) == sizeof(float));
4397 *(float *)pu32Val = 256.0f; /* VGPU9. Not applicable to DX11. */
4398 break;
4399
4400 case SVGA3D_DEVCAP_MAX_SHADER_TEXTURES:
4401 /* Obsolete */
4402 break;
4403
4404 case SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH:
4405 case SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT:
4406 if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
4407 *pu32Val = 16384;
4408 else if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4409 *pu32Val = 8192;
4410 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_3)
4411 *pu32Val = 4096;
4412 else
4413 *pu32Val = 2048;
4414 break;
4415
4416 case SVGA3D_DEVCAP_MAX_VOLUME_EXTENT:
4417 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4418 *pu32Val = 2048;
4419 else
4420 *pu32Val = 256;
4421 break;
4422
4423 case SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT:
4424 if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
4425 *pu32Val = 16384;
4426 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_3)
4427 *pu32Val = 8192;
4428 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
4429 *pu32Val = 2048;
4430 else
4431 *pu32Val = 128;
4432 break;
4433
4434 case SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO:
4435 /* Obsolete */
4436 break;
4437
4438 case SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY:
4439 if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
4440 *pu32Val = D3D11_REQ_MAXANISOTROPY;
4441 else
4442 *pu32Val = 2; // D3D_FL9_1_DEFAULT_MAX_ANISOTROPY;
4443 break;
4444
4445 case SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT:
4446 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4447 *pu32Val = UINT32_MAX;
4448 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
4449 *pu32Val = 1048575; // D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT;
4450 else
4451 *pu32Val = 65535; // D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT;
4452 break;
4453
4454 case SVGA3D_DEVCAP_MAX_VERTEX_INDEX:
4455 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4456 *pu32Val = UINT32_MAX;
4457 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
4458 *pu32Val = 1048575;
4459 else
4460 *pu32Val = 65534;
4461 break;
4462
4463 case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS:
4464 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4465 *pu32Val = UINT32_MAX;
4466 else
4467 *pu32Val = 512;
4468 break;
4469
4470 case SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS:
4471 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4472 *pu32Val = UINT32_MAX;
4473 else
4474 *pu32Val = 512;
4475 break;
4476
4477 case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS:
4478 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4479 *pu32Val = 4096;
4480 else
4481 *pu32Val = 32;
4482 break;
4483
4484 case SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS:
4485 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4486 *pu32Val = 4096;
4487 else
4488 *pu32Val = 32;
4489 break;
4490
4491 case SVGA3D_DEVCAP_TEXTURE_OPS:
4492 /* Obsolete */
4493 break;
4494
4495 case SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8:
4496 case SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8:
4497 case SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10:
4498 case SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5:
4499 case SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5:
4500 case SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4:
4501 case SVGA3D_DEVCAP_SURFACEFMT_R5G6B5:
4502 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16:
4503 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8:
4504 case SVGA3D_DEVCAP_SURFACEFMT_ALPHA8:
4505 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8:
4506 case SVGA3D_DEVCAP_SURFACEFMT_Z_D16:
4507 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8:
4508 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8:
4509 case SVGA3D_DEVCAP_SURFACEFMT_DXT1:
4510 case SVGA3D_DEVCAP_SURFACEFMT_DXT2:
4511 case SVGA3D_DEVCAP_SURFACEFMT_DXT3:
4512 case SVGA3D_DEVCAP_SURFACEFMT_DXT4:
4513 case SVGA3D_DEVCAP_SURFACEFMT_DXT5:
4514 case SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8:
4515 case SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10:
4516 case SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8:
4517 case SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8:
4518 case SVGA3D_DEVCAP_SURFACEFMT_CxV8U8:
4519 case SVGA3D_DEVCAP_SURFACEFMT_R_S10E5:
4520 case SVGA3D_DEVCAP_SURFACEFMT_R_S23E8:
4521 case SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5:
4522 case SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8:
4523 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5:
4524 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8:
4525 case SVGA3D_DEVCAP_SURFACEFMT_V16U16:
4526 case SVGA3D_DEVCAP_SURFACEFMT_G16R16:
4527 case SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16:
4528 case SVGA3D_DEVCAP_SURFACEFMT_UYVY:
4529 case SVGA3D_DEVCAP_SURFACEFMT_YUY2:
4530 case SVGA3D_DEVCAP_SURFACEFMT_NV12:
4531 case SVGA3D_DEVCAP_DEAD10: /* SVGA3D_DEVCAP_SURFACEFMT_AYUV */
4532 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF16:
4533 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF24:
4534 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT:
4535 case SVGA3D_DEVCAP_SURFACEFMT_ATI1:
4536 case SVGA3D_DEVCAP_SURFACEFMT_ATI2:
4537 case SVGA3D_DEVCAP_SURFACEFMT_YV12:
4538 {
4539 SVGA3dSurfaceFormat const enmFormat = vmsvgaDXDevCapSurfaceFmt2Format(idx3dCaps);
4540 rc = vmsvgaDXCheckFormatSupportPreDX(pState, enmFormat, pu32Val);
4541 break;
4542 }
4543
4544 case SVGA3D_DEVCAP_MISSING62:
4545 /* Unused */
4546 break;
4547
4548 case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES:
4549 /* Obsolete */
4550 break;
4551
4552 case SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS:
4553 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
4554 *pu32Val = 8;
4555 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_3)
4556 *pu32Val = 4; // D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT
4557 else
4558 *pu32Val = 1; // D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT
4559 break;
4560
4561 case SVGA3D_DEVCAP_DEAD4: /* SVGA3D_DEVCAP_MULTISAMPLE_NONMASKABLESAMPLES */
4562 case SVGA3D_DEVCAP_DEAD5: /* SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES */
4563 *pu32Val = (1 << (2-1)) | (1 << (4-1)) | (1 << (8-1)); /* 2x, 4x, 8x */
4564 break;
4565
4566 case SVGA3D_DEVCAP_DEAD7: /* SVGA3D_DEVCAP_ALPHATOCOVERAGE */
4567 /* Obsolete */
4568 break;
4569
4570 case SVGA3D_DEVCAP_DEAD6: /* SVGA3D_DEVCAP_SUPERSAMPLE */
4571 /* Obsolete */
4572 break;
4573
4574 case SVGA3D_DEVCAP_AUTOGENMIPMAPS:
4575 *pu32Val = 1;
4576 break;
4577
4578 case SVGA3D_DEVCAP_MAX_CONTEXT_IDS:
4579 *pu32Val = SVGA3D_MAX_CONTEXT_IDS;
4580 break;
4581
4582 case SVGA3D_DEVCAP_MAX_SURFACE_IDS:
4583 *pu32Val = SVGA3D_MAX_SURFACE_IDS;
4584 break;
4585
4586 case SVGA3D_DEVCAP_DEAD1:
4587 /* Obsolete */
4588 break;
4589
4590 case SVGA3D_DEVCAP_DEAD8: /* SVGA3D_DEVCAP_VIDEO_DECODE */
4591 /* Obsolete */
4592 break;
4593
4594 case SVGA3D_DEVCAP_DEAD9: /* SVGA3D_DEVCAP_VIDEO_PROCESS */
4595 /* Obsolete */
4596 break;
4597
4598 case SVGA3D_DEVCAP_LINE_AA:
4599 *pu32Val = 1;
4600 break;
4601
4602 case SVGA3D_DEVCAP_LINE_STIPPLE:
4603 *pu32Val = 0; /* DX11 does not seem to support this directly. */
4604 break;
4605
4606 case SVGA3D_DEVCAP_MAX_LINE_WIDTH:
4607 AssertCompile(sizeof(uint32_t) == sizeof(float));
4608 *(float *)pu32Val = 1.0f;
4609 break;
4610
4611 case SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH:
4612 AssertCompile(sizeof(uint32_t) == sizeof(float));
4613 *(float *)pu32Val = 1.0f;
4614 break;
4615
4616 case SVGA3D_DEVCAP_DEAD3: /* Old SVGA3D_DEVCAP_LOGICOPS */
4617 /* Deprecated. */
4618 AssertCompile(SVGA3D_DEVCAP_DEAD3 == 92); /* Newer SVGA headers redefine this. */
4619 break;
4620
4621 case SVGA3D_DEVCAP_TS_COLOR_KEY:
4622 *pu32Val = 0; /* DX11 does not seem to support this directly. */
4623 break;
4624
4625 case SVGA3D_DEVCAP_DEAD2:
4626 break;
4627
4628 case SVGA3D_DEVCAP_DXCONTEXT:
4629 *pu32Val = 1;
4630 break;
4631
4632 case SVGA3D_DEVCAP_DEAD11: /* SVGA3D_DEVCAP_MAX_TEXTURE_ARRAY_SIZE */
4633 *pu32Val = D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
4634 break;
4635
4636 case SVGA3D_DEVCAP_DX_MAX_VERTEXBUFFERS:
4637 *pu32Val = D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT;
4638 break;
4639
4640 case SVGA3D_DEVCAP_DX_MAX_CONSTANT_BUFFERS:
4641 *pu32Val = D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT;
4642 break;
4643
4644 case SVGA3D_DEVCAP_DX_PROVOKING_VERTEX:
4645 *pu32Val = 0; /* boolean */
4646 break;
4647
4648 case SVGA3D_DEVCAP_DXFMT_X8R8G8B8:
4649 case SVGA3D_DEVCAP_DXFMT_A8R8G8B8:
4650 case SVGA3D_DEVCAP_DXFMT_R5G6B5:
4651 case SVGA3D_DEVCAP_DXFMT_X1R5G5B5:
4652 case SVGA3D_DEVCAP_DXFMT_A1R5G5B5:
4653 case SVGA3D_DEVCAP_DXFMT_A4R4G4B4:
4654 case SVGA3D_DEVCAP_DXFMT_Z_D32:
4655 case SVGA3D_DEVCAP_DXFMT_Z_D16:
4656 case SVGA3D_DEVCAP_DXFMT_Z_D24S8:
4657 case SVGA3D_DEVCAP_DXFMT_Z_D15S1:
4658 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8:
4659 case SVGA3D_DEVCAP_DXFMT_LUMINANCE4_ALPHA4:
4660 case SVGA3D_DEVCAP_DXFMT_LUMINANCE16:
4661 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8_ALPHA8:
4662 case SVGA3D_DEVCAP_DXFMT_DXT1:
4663 case SVGA3D_DEVCAP_DXFMT_DXT2:
4664 case SVGA3D_DEVCAP_DXFMT_DXT3:
4665 case SVGA3D_DEVCAP_DXFMT_DXT4:
4666 case SVGA3D_DEVCAP_DXFMT_DXT5:
4667 case SVGA3D_DEVCAP_DXFMT_BUMPU8V8:
4668 case SVGA3D_DEVCAP_DXFMT_BUMPL6V5U5:
4669 case SVGA3D_DEVCAP_DXFMT_BUMPX8L8V8U8:
4670 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD1:
4671 case SVGA3D_DEVCAP_DXFMT_ARGB_S10E5:
4672 case SVGA3D_DEVCAP_DXFMT_ARGB_S23E8:
4673 case SVGA3D_DEVCAP_DXFMT_A2R10G10B10:
4674 case SVGA3D_DEVCAP_DXFMT_V8U8:
4675 case SVGA3D_DEVCAP_DXFMT_Q8W8V8U8:
4676 case SVGA3D_DEVCAP_DXFMT_CxV8U8:
4677 case SVGA3D_DEVCAP_DXFMT_X8L8V8U8:
4678 case SVGA3D_DEVCAP_DXFMT_A2W10V10U10:
4679 case SVGA3D_DEVCAP_DXFMT_ALPHA8:
4680 case SVGA3D_DEVCAP_DXFMT_R_S10E5:
4681 case SVGA3D_DEVCAP_DXFMT_R_S23E8:
4682 case SVGA3D_DEVCAP_DXFMT_RG_S10E5:
4683 case SVGA3D_DEVCAP_DXFMT_RG_S23E8:
4684 case SVGA3D_DEVCAP_DXFMT_BUFFER:
4685 case SVGA3D_DEVCAP_DXFMT_Z_D24X8:
4686 case SVGA3D_DEVCAP_DXFMT_V16U16:
4687 case SVGA3D_DEVCAP_DXFMT_G16R16:
4688 case SVGA3D_DEVCAP_DXFMT_A16B16G16R16:
4689 case SVGA3D_DEVCAP_DXFMT_UYVY:
4690 case SVGA3D_DEVCAP_DXFMT_YUY2:
4691 case SVGA3D_DEVCAP_DXFMT_NV12:
4692 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD2: /* SVGA3D_DEVCAP_DXFMT_AYUV */
4693 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_TYPELESS:
4694 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_UINT:
4695 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_SINT:
4696 case SVGA3D_DEVCAP_DXFMT_R32G32B32_TYPELESS:
4697 case SVGA3D_DEVCAP_DXFMT_R32G32B32_FLOAT:
4698 case SVGA3D_DEVCAP_DXFMT_R32G32B32_UINT:
4699 case SVGA3D_DEVCAP_DXFMT_R32G32B32_SINT:
4700 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_TYPELESS:
4701 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UINT:
4702 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SNORM:
4703 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SINT:
4704 case SVGA3D_DEVCAP_DXFMT_R32G32_TYPELESS:
4705 case SVGA3D_DEVCAP_DXFMT_R32G32_UINT:
4706 case SVGA3D_DEVCAP_DXFMT_R32G32_SINT:
4707 case SVGA3D_DEVCAP_DXFMT_R32G8X24_TYPELESS:
4708 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT_S8X24_UINT:
4709 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT_X8X24:
4710 case SVGA3D_DEVCAP_DXFMT_X32_G8X24_UINT:
4711 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_TYPELESS:
4712 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UINT:
4713 case SVGA3D_DEVCAP_DXFMT_R11G11B10_FLOAT:
4714 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_TYPELESS:
4715 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM:
4716 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM_SRGB:
4717 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UINT:
4718 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SINT:
4719 case SVGA3D_DEVCAP_DXFMT_R16G16_TYPELESS:
4720 case SVGA3D_DEVCAP_DXFMT_R16G16_UINT:
4721 case SVGA3D_DEVCAP_DXFMT_R16G16_SINT:
4722 case SVGA3D_DEVCAP_DXFMT_R32_TYPELESS:
4723 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT:
4724 case SVGA3D_DEVCAP_DXFMT_R32_UINT:
4725 case SVGA3D_DEVCAP_DXFMT_R32_SINT:
4726 case SVGA3D_DEVCAP_DXFMT_R24G8_TYPELESS:
4727 case SVGA3D_DEVCAP_DXFMT_D24_UNORM_S8_UINT:
4728 case SVGA3D_DEVCAP_DXFMT_R24_UNORM_X8:
4729 case SVGA3D_DEVCAP_DXFMT_X24_G8_UINT:
4730 case SVGA3D_DEVCAP_DXFMT_R8G8_TYPELESS:
4731 case SVGA3D_DEVCAP_DXFMT_R8G8_UNORM:
4732 case SVGA3D_DEVCAP_DXFMT_R8G8_UINT:
4733 case SVGA3D_DEVCAP_DXFMT_R8G8_SINT:
4734 case SVGA3D_DEVCAP_DXFMT_R16_TYPELESS:
4735 case SVGA3D_DEVCAP_DXFMT_R16_UNORM:
4736 case SVGA3D_DEVCAP_DXFMT_R16_UINT:
4737 case SVGA3D_DEVCAP_DXFMT_R16_SNORM:
4738 case SVGA3D_DEVCAP_DXFMT_R16_SINT:
4739 case SVGA3D_DEVCAP_DXFMT_R8_TYPELESS:
4740 case SVGA3D_DEVCAP_DXFMT_R8_UNORM:
4741 case SVGA3D_DEVCAP_DXFMT_R8_UINT:
4742 case SVGA3D_DEVCAP_DXFMT_R8_SNORM:
4743 case SVGA3D_DEVCAP_DXFMT_R8_SINT:
4744 case SVGA3D_DEVCAP_DXFMT_P8:
4745 case SVGA3D_DEVCAP_DXFMT_R9G9B9E5_SHAREDEXP:
4746 case SVGA3D_DEVCAP_DXFMT_R8G8_B8G8_UNORM:
4747 case SVGA3D_DEVCAP_DXFMT_G8R8_G8B8_UNORM:
4748 case SVGA3D_DEVCAP_DXFMT_BC1_TYPELESS:
4749 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM_SRGB:
4750 case SVGA3D_DEVCAP_DXFMT_BC2_TYPELESS:
4751 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM_SRGB:
4752 case SVGA3D_DEVCAP_DXFMT_BC3_TYPELESS:
4753 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM_SRGB:
4754 case SVGA3D_DEVCAP_DXFMT_BC4_TYPELESS:
4755 case SVGA3D_DEVCAP_DXFMT_ATI1:
4756 case SVGA3D_DEVCAP_DXFMT_BC4_SNORM:
4757 case SVGA3D_DEVCAP_DXFMT_BC5_TYPELESS:
4758 case SVGA3D_DEVCAP_DXFMT_ATI2:
4759 case SVGA3D_DEVCAP_DXFMT_BC5_SNORM:
4760 case SVGA3D_DEVCAP_DXFMT_R10G10B10_XR_BIAS_A2_UNORM:
4761 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_TYPELESS:
4762 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM_SRGB:
4763 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_TYPELESS:
4764 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM_SRGB:
4765 case SVGA3D_DEVCAP_DXFMT_Z_DF16:
4766 case SVGA3D_DEVCAP_DXFMT_Z_DF24:
4767 case SVGA3D_DEVCAP_DXFMT_Z_D24S8_INT:
4768 case SVGA3D_DEVCAP_DXFMT_YV12:
4769 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_FLOAT:
4770 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_FLOAT:
4771 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UNORM:
4772 case SVGA3D_DEVCAP_DXFMT_R32G32_FLOAT:
4773 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UNORM:
4774 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SNORM:
4775 case SVGA3D_DEVCAP_DXFMT_R16G16_FLOAT:
4776 case SVGA3D_DEVCAP_DXFMT_R16G16_UNORM:
4777 case SVGA3D_DEVCAP_DXFMT_R16G16_SNORM:
4778 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT:
4779 case SVGA3D_DEVCAP_DXFMT_R8G8_SNORM:
4780 case SVGA3D_DEVCAP_DXFMT_R16_FLOAT:
4781 case SVGA3D_DEVCAP_DXFMT_D16_UNORM:
4782 case SVGA3D_DEVCAP_DXFMT_A8_UNORM:
4783 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM:
4784 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM:
4785 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM:
4786 case SVGA3D_DEVCAP_DXFMT_B5G6R5_UNORM:
4787 case SVGA3D_DEVCAP_DXFMT_B5G5R5A1_UNORM:
4788 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM:
4789 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM:
4790 case SVGA3D_DEVCAP_DXFMT_BC4_UNORM:
4791 case SVGA3D_DEVCAP_DXFMT_BC5_UNORM:
4792 case SVGA3D_DEVCAP_DXFMT_BC6H_TYPELESS:
4793 case SVGA3D_DEVCAP_DXFMT_BC6H_UF16:
4794 case SVGA3D_DEVCAP_DXFMT_BC6H_SF16:
4795 case SVGA3D_DEVCAP_DXFMT_BC7_TYPELESS:
4796 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM:
4797 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM_SRGB:
4798 {
4799 SVGA3dSurfaceFormat const enmFormat = vmsvgaDXDevCapDxfmt2Format(idx3dCaps);
4800 rc = vmsvgaDXCheckFormatSupport(pState, enmFormat, pu32Val);
4801 break;
4802 }
4803
4804 case SVGA3D_DEVCAP_SM41:
4805 *pu32Val = 1; /* boolean */
4806 break;
4807
4808 case SVGA3D_DEVCAP_MULTISAMPLE_2X:
4809 *pu32Val = RT_BOOL(pState->pBackend->dxDevice.MultisampleCountMask & (1 << (2 - 1))); /* boolean */
4810 break;
4811
4812 case SVGA3D_DEVCAP_MULTISAMPLE_4X:
4813 *pu32Val = RT_BOOL(pState->pBackend->dxDevice.MultisampleCountMask & (1 << (4 - 1))); /* boolean */
4814 break;
4815
4816 case SVGA3D_DEVCAP_MS_FULL_QUALITY:
4817 *pu32Val = 0; /* boolean */
4818 break;
4819
4820 case SVGA3D_DEVCAP_LOGICOPS:
4821 AssertCompile(SVGA3D_DEVCAP_LOGICOPS == 248);
4822 *pu32Val = 0; /* boolean */
4823 break;
4824
4825 case SVGA3D_DEVCAP_LOGIC_BLENDOPS:
4826 *pu32Val = 0; /* boolean */
4827 break;
4828
4829 case SVGA3D_DEVCAP_RESERVED_1:
4830 break;
4831
4832 case SVGA3D_DEVCAP_RESERVED_2:
4833 break;
4834
4835 case SVGA3D_DEVCAP_SM5:
4836 *pu32Val = 1; /* boolean */
4837 break;
4838
4839 case SVGA3D_DEVCAP_MULTISAMPLE_8X:
4840 *pu32Val = RT_BOOL(pState->pBackend->dxDevice.MultisampleCountMask & (1 << (8 - 1))); /* boolean */
4841 break;
4842
4843 case SVGA3D_DEVCAP_MAX:
4844 case SVGA3D_DEVCAP_INVALID:
4845 rc = VERR_NOT_SUPPORTED;
4846 break;
4847 }
4848
4849 return rc;
4850}
4851
4852
4853static DECLCALLBACK(int) vmsvga3dBackChangeMode(PVGASTATECC pThisCC)
4854{
4855 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4856 AssertReturn(pState, VERR_INVALID_STATE);
4857
4858 return VINF_SUCCESS;
4859}
4860
4861
4862static DECLCALLBACK(int) vmsvga3dBackSurfaceCopy(PVGASTATECC pThisCC, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src,
4863 uint32_t cCopyBoxes, SVGA3dCopyBox *pBox)
4864{
4865 RT_NOREF(cCopyBoxes, pBox);
4866
4867 LogFunc(("src sid %d -> dst sid %d\n", src.sid, dest.sid));
4868
4869 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4870 AssertReturn(pState, VERR_INVALID_STATE);
4871
4872 PVMSVGA3DBACKEND pBackend = pState->pBackend;
4873
4874 PVMSVGA3DSURFACE pSrcSurface;
4875 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, src.sid, &pSrcSurface);
4876 AssertRCReturn(rc, rc);
4877
4878 PVMSVGA3DSURFACE pDstSurface;
4879 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, dest.sid, &pDstSurface);
4880 AssertRCReturn(rc, rc);
4881
4882 LogFunc(("src%s cid %d -> dst%s cid %d\n",
4883 pSrcSurface->pBackendSurface ? "" : " sysmem",
4884 pSrcSurface ? pSrcSurface->idAssociatedContext : SVGA_ID_INVALID,
4885 pDstSurface->pBackendSurface ? "" : " sysmem",
4886 pDstSurface ? pDstSurface->idAssociatedContext : SVGA_ID_INVALID));
4887
4888 //DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
4889 //AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
4890
4891 if (pSrcSurface->pBackendSurface)
4892 {
4893 if (pDstSurface->pBackendSurface == NULL)
4894 {
4895 /* Create the target if it can be used as a device context shared resource (render or screen target). */
4896 if (pBackend->fSingleDevice || dxIsSurfaceShareable(pDstSurface))
4897 {
4898 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, NULL, pDstSurface);
4899 AssertRCReturn(rc, rc);
4900 }
4901 }
4902
4903 if (pDstSurface->pBackendSurface)
4904 {
4905 /* Surface -> Surface. */
4906 /* Expect both of them to be shared surfaces created by the backend context. */
4907 Assert(pSrcSurface->idAssociatedContext == DX_CID_BACKEND && pDstSurface->idAssociatedContext == DX_CID_BACKEND);
4908
4909 /* Wait for the source surface to finish drawing. */
4910 dxSurfaceWait(pState, pSrcSurface, DX_CID_BACKEND);
4911
4912 DXDEVICE *pDXDevice = &pBackend->dxDevice;
4913
4914 /* Clip the box. */
4915 PVMSVGA3DMIPMAPLEVEL pSrcMipLevel;
4916 rc = vmsvga3dMipmapLevel(pSrcSurface, src.face, src.mipmap, &pSrcMipLevel);
4917 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
4918
4919 PVMSVGA3DMIPMAPLEVEL pDstMipLevel;
4920 rc = vmsvga3dMipmapLevel(pDstSurface, dest.face, dest.mipmap, &pDstMipLevel);
4921 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
4922
4923 SVGA3dCopyBox clipBox = *pBox;
4924 vmsvgaR3ClipCopyBox(&pSrcMipLevel->mipmapSize, &pDstMipLevel->mipmapSize, &clipBox);
4925
4926 UINT DstSubresource = vmsvga3dCalcSubresource(dest.mipmap, dest.face, pDstSurface->cLevels);
4927 UINT DstX = clipBox.x;
4928 UINT DstY = clipBox.y;
4929 UINT DstZ = clipBox.z;
4930
4931 UINT SrcSubresource = vmsvga3dCalcSubresource(src.mipmap, src.face, pSrcSurface->cLevels);
4932 D3D11_BOX SrcBox;
4933 SrcBox.left = clipBox.srcx;
4934 SrcBox.top = clipBox.srcy;
4935 SrcBox.front = clipBox.srcz;
4936 SrcBox.right = clipBox.srcx + clipBox.w;
4937 SrcBox.bottom = clipBox.srcy + clipBox.h;
4938 SrcBox.back = clipBox.srcz + clipBox.d;
4939
4940 Assert(cCopyBoxes == 1); /** @todo */
4941
4942 ID3D11Resource *pDstResource;
4943 ID3D11Resource *pSrcResource;
4944 pDstResource = dxResource(pState, pDstSurface, NULL);
4945 pSrcResource = dxResource(pState, pSrcSurface, NULL);
4946
4947 pDXDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
4948 pSrcResource, SrcSubresource, &SrcBox);
4949
4950 pDstSurface->pBackendSurface->cidDrawing = DX_CID_BACKEND;
4951 }
4952 else
4953 {
4954 /* Surface -> Memory. */
4955 AssertFailed(); /** @todo implement */
4956 }
4957 }
4958 else
4959 {
4960 /* Memory -> Surface. */
4961 AssertFailed(); /** @todo implement */
4962 }
4963
4964 return rc;
4965}
4966
4967
4968static DECLCALLBACK(void) vmsvga3dBackUpdateHostScreenViewport(PVGASTATECC pThisCC, uint32_t idScreen, VMSVGAVIEWPORT const *pOldViewport)
4969{
4970 RT_NOREF(pThisCC, idScreen, pOldViewport);
4971 /** @todo Scroll the screen content without requiring the guest to redraw. */
4972}
4973
4974
4975static DECLCALLBACK(int) vmsvga3dBackSurfaceUpdateHeapBuffers(PVGASTATECC pThisCC, PVMSVGA3DSURFACE pSurface)
4976{
4977 /** @todo */
4978 RT_NOREF(pThisCC, pSurface);
4979 return VERR_NOT_IMPLEMENTED;
4980}
4981
4982
4983/*
4984 *
4985 * VGPU9 callbacks. Not implemented.
4986 *
4987 */
4988/** @todo later */
4989
4990/**
4991 * Create a new 3d context
4992 *
4993 * @returns VBox status code.
4994 * @param pThisCC The VGA/VMSVGA state for ring-3.
4995 * @param cid Context id
4996 */
4997static DECLCALLBACK(int) vmsvga3dBackContextDefine(PVGASTATECC pThisCC, uint32_t cid)
4998{
4999 RT_NOREF(cid);
5000
5001 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
5002 AssertReturn(pState, VERR_INVALID_STATE);
5003
5004 DEBUG_BREAKPOINT_TEST();
5005 return VERR_NOT_IMPLEMENTED;
5006}
5007
5008
5009/**
5010 * Destroy an existing 3d context
5011 *
5012 * @returns VBox status code.
5013 * @param pThisCC The VGA/VMSVGA state for ring-3.
5014 * @param cid Context id
5015 */
5016static DECLCALLBACK(int) vmsvga3dBackContextDestroy(PVGASTATECC pThisCC, uint32_t cid)
5017{
5018 RT_NOREF(cid);
5019
5020 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
5021 AssertReturn(pState, VERR_INVALID_STATE);
5022
5023 DEBUG_BREAKPOINT_TEST();
5024 return VINF_SUCCESS;
5025}
5026
5027
5028static DECLCALLBACK(int) vmsvga3dBackSetTransform(PVGASTATECC pThisCC, uint32_t cid, SVGA3dTransformType type, float matrix[16])
5029{
5030 RT_NOREF(cid, type, matrix);
5031
5032 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
5033 AssertReturn(pState, VERR_INVALID_STATE);
5034
5035 DEBUG_BREAKPOINT_TEST();
5036 return VINF_SUCCESS;
5037}
5038
5039
5040static DECLCALLBACK(int) vmsvga3dBackSetZRange(PVGASTATECC pThisCC, uint32_t cid, SVGA3dZRange zRange)
5041{
5042 RT_NOREF(cid, zRange);
5043
5044 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
5045 AssertReturn(pState, VERR_INVALID_STATE);
5046
5047 DEBUG_BREAKPOINT_TEST();
5048 return VINF_SUCCESS;
5049}
5050
5051
5052static DECLCALLBACK(int) vmsvga3dBackSetRenderState(PVGASTATECC pThisCC, uint32_t cid, uint32_t cRenderStates, SVGA3dRenderState *pRenderState)
5053{
5054 RT_NOREF(cid, cRenderStates, pRenderState);
5055
5056 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
5057 AssertReturn(pState, VERR_INVALID_STATE);
5058
5059 DEBUG_BREAKPOINT_TEST();
5060 return VINF_SUCCESS;
5061}
5062
5063
5064static DECLCALLBACK(int) vmsvga3dBackSetRenderTarget(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRenderTargetType type, SVGA3dSurfaceImageId target)
5065{
5066 RT_NOREF(cid, type, target);
5067
5068 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
5069 AssertReturn(pState, VERR_INVALID_STATE);
5070
5071 DEBUG_BREAKPOINT_TEST();
5072 return VINF_SUCCESS;
5073}
5074
5075
5076static DECLCALLBACK(int) vmsvga3dBackSetTextureState(PVGASTATECC pThisCC, uint32_t cid, uint32_t cTextureStates, SVGA3dTextureState *pTextureState)
5077{
5078 RT_NOREF(cid, cTextureStates, pTextureState);
5079
5080 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
5081 AssertReturn(pState, VERR_INVALID_STATE);
5082
5083 DEBUG_BREAKPOINT_TEST();
5084 return VINF_SUCCESS;
5085}
5086