VirtualBox

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

Last change on this file since 91823 was 91823, checked in by vboxsync, 3 years ago

Devices/Graphics: parser improvements; logging: bugref:9830

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 295.3 KB
Line 
1/* $Id: DevVGA-SVGA3d-win-dx.cpp 91823 2021-10-18 10:12:46Z vboxsync $ */
2/** @file
3 * DevVMWare - VMWare SVGA device
4 */
5
6/*
7 * Copyright (C) 2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DEV_VMSVGA
23#include <VBox/AssertGuest.h>
24#include <VBox/log.h>
25#include <VBox/vmm/pdmdev.h>
26#include <VBox/vmm/pgm.h>
27
28#include <iprt/assert.h>
29#include <iprt/avl.h>
30#include <iprt/errcore.h>
31#include <iprt/mem.h>
32
33#include <VBoxVideo.h> /* required by DevVGA.h */
34#include <VBoxVideo3D.h>
35
36/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
37#include "DevVGA.h"
38
39#include "DevVGA-SVGA.h"
40#include "DevVGA-SVGA3d.h"
41#include "DevVGA-SVGA3d-internal.h"
42#include "DevVGA-SVGA3d-dx-shader.h"
43
44#include <d3d11.h>
45
46
47/** Fake ID for the backend DX context. The context creates all shared textures. */
48#define DX_CID_BACKEND UINT32_C(0xfffffffe)
49
50#define DX_RELEASE_ARRAY(a_Count, a_papArray) do { \
51 for (uint32_t i = 0; i < (a_Count); ++i) \
52 D3D_RELEASE((a_papArray)[i]); \
53} while (0)
54
55typedef struct DXDEVICE
56{
57 ID3D11Device *pDevice; /* Device. */
58 ID3D11DeviceContext *pImmediateContext; /* Corresponding context. */
59 IDXGIFactory *pDxgiFactory; /* DXGI Factory. */
60 D3D_FEATURE_LEVEL FeatureLevel;
61
62 /* Staging buffer for transfer to surface buffers. */
63 ID3D11Buffer *pStagingBuffer; /* The staging buffer resource. */
64 uint32_t cbStagingBuffer; /* Current size of the staging buffer resource. */
65} DXDEVICE;
66
67/* What kind of resource has been created for the VMSVGA3D surface. */
68typedef enum VMSVGA3DBACKRESTYPE
69{
70 VMSVGA3D_RESTYPE_NONE = 0,
71 VMSVGA3D_RESTYPE_SCREEN_TARGET = 1,
72 VMSVGA3D_RESTYPE_TEXTURE_1D = 2,
73 VMSVGA3D_RESTYPE_TEXTURE = 3,
74 VMSVGA3D_RESTYPE_CUBE_TEXTURE = 4,
75 VMSVGA3D_RESTYPE_TEXTURE_3D = 5,
76 VMSVGA3D_RESTYPE_BUFFER = 6,
77} VMSVGA3DBACKRESTYPE;
78
79typedef struct VMSVGA3DBACKENDSURFACE
80{
81 VMSVGA3DBACKRESTYPE enmResType;
82 DXGI_FORMAT enmDxgiFormat;
83 union
84 {
85 ID3D11Resource *pResource;
86 ID3D11Texture2D *pTexture2D;
87 ID3D11Texture3D *pTexture3D;
88 ID3D11Buffer *pBuffer;
89 } u;
90
91 ID3D11Texture2D *pDynamicTexture; /* For screen updates from memory. */ /** @todo One for all screens. */
92 ID3D11Texture2D *pStagingTexture; /* For Reading the screen content. */ /** @todo One for all screens. */
93 ID3D11Texture3D *pDynamicTexture3D; /* For screen updates from memory. */ /** @todo One for all screens. */
94 ID3D11Texture3D *pStagingTexture3D; /* For Reading the screen content. */ /** @todo One for all screens. */
95
96 /* Screen targets are created as shared surfaces. */
97 HANDLE SharedHandle; /* The shared handle of this structure. */
98
99 /* DX context which last rendered to the texture.
100 * This is only for render targets and screen targets, which can be shared between contexts.
101 * The backend context (cid == DX_CID_BACKEND) can also be a drawing context.
102 */
103 uint32_t cidDrawing;
104
105 /** AVL tree containing DXSHAREDTEXTURE structures. */
106 AVLU32TREE SharedTextureTree;
107
108} VMSVGA3DBACKENDSURFACE;
109
110/* "The only resources that can be shared are 2D non-mipmapped textures." */
111typedef struct DXSHAREDTEXTURE
112{
113 AVLU32NODECORE Core; /* Key is context id which opened this texture. */
114 ID3D11Texture2D *pTexture; /* The opened shared texture. */
115 uint32_t sid; /* Surface id. */
116} DXSHAREDTEXTURE;
117
118
119typedef struct VMSVGAHWSCREEN
120{
121 ID3D11Texture2D *pTexture; /* Shared texture for the screen content. Only used as CopyResource target. */
122 IDXGIResource *pDxgiResource; /* Interface of the texture. */
123 IDXGIKeyedMutex *pDXGIKeyedMutex; /* Synchronization interface for the render device. */
124 HANDLE SharedHandle; /* The shared handle of this structure. */
125 uint32_t sidScreenTarget; /* The source surface for this screen. */
126} VMSVGAHWSCREEN;
127
128
129typedef struct DXELEMENTLAYOUT
130{
131 ID3D11InputLayout *pElementLayout;
132 uint32_t cElementDesc;
133 D3D11_INPUT_ELEMENT_DESC aElementDesc[32];
134} DXELEMENTLAYOUT;
135
136typedef struct DXSHADER
137{
138 SVGA3dShaderType enmShaderType;
139 union
140 {
141 ID3D11DeviceChild *pShader; /* All. */
142 ID3D11VertexShader *pVertexShader; /* SVGA3D_SHADERTYPE_VS */
143 ID3D11PixelShader *pPixelShader; /* SVGA3D_SHADERTYPE_PS */
144 ID3D11GeometryShader *pGeometryShader; /* SVGA3D_SHADERTYPE_GS */
145 ID3D11HullShader *pHullShader; /* SVGA3D_SHADERTYPE_HS */
146 ID3D11DomainShader *pDomainShader; /* SVGA3D_SHADERTYPE_DS */
147 ID3D11ComputeShader *pComputeShader; /* SVGA3D_SHADERTYPE_CS */
148 };
149 void *pvDXBC;
150 uint32_t cbDXBC;
151
152 uint32_t soid; /* Stream output declarations for geometry shaders. */
153} DXSHADER;
154
155typedef struct DXSTREAMOUTPUT
156{
157 UINT cDeclarationEntry;
158 D3D11_SO_DECLARATION_ENTRY aDeclarationEntry[SVGA3D_MAX_STREAMOUT_DECLS];
159} DXSTREAMOUTPUT;
160
161#define DX_DEFERRED_SET_RENDER_TARGETS
162typedef struct VMSVGA3DBACKENDDXCONTEXT
163{
164 DXDEVICE device; /* DX device interfaces for this context operations. */
165
166 /* Arrays for Context-Object Tables. Number of entries depends on COTable size. */
167 uint32_t cBlendState; /* Number of entries in the papBlendState array. */
168 uint32_t cDepthStencilState; /* papDepthStencilState */
169 uint32_t cSamplerState; /* papSamplerState */
170 uint32_t cRasterizerState; /* papRasterizerState */
171 uint32_t cElementLayout; /* papElementLayout */
172 uint32_t cRenderTargetView; /* papRenderTargetView */
173 uint32_t cDepthStencilView; /* papDepthStencilView */
174 uint32_t cShaderResourceView; /* papShaderResourceView */
175 uint32_t cQuery; /* papQuery */
176 uint32_t cShader; /* papShader */
177 uint32_t cStreamOutput; /* papStreamOutput */
178 ID3D11BlendState **papBlendState;
179 ID3D11DepthStencilState **papDepthStencilState;
180 ID3D11SamplerState **papSamplerState;
181 ID3D11RasterizerState **papRasterizerState;
182 DXELEMENTLAYOUT *paElementLayout;
183 ID3D11RenderTargetView **papRenderTargetView;
184 ID3D11DepthStencilView **papDepthStencilView;
185 ID3D11ShaderResourceView **papShaderResourceView;
186 ID3D11Query **papQuery;
187 DXSHADER *paShader;
188 DXSTREAMOUTPUT *paStreamOutput;
189
190#ifdef DX_DEFERRED_SET_RENDER_TARGETS
191 struct
192 {
193 ID3D11RenderTargetView *papRenderTargetViews[SVGA3D_MAX_RENDER_TARGETS];
194 uint32_t cRenderTargetViews;
195 ID3D11DepthStencilView *pDepthStencilView;
196 } state;
197#endif
198
199 uint32_t cSOTarget; /* How many SO targets are currently set (SetSOTargets) */
200} VMSVGA3DBACKENDDXCONTEXT;
201
202typedef HRESULT FN_D3D_DISASSEMBLE(LPCVOID pSrcData, SIZE_T SrcDataSize, UINT Flags, LPCSTR szComments, ID3D10Blob **ppDisassembly);
203typedef FN_D3D_DISASSEMBLE *PFN_D3D_DISASSEMBLE;
204
205typedef struct VMSVGA3DBACKEND
206{
207 RTLDRMOD hD3D11;
208 PFN_D3D11_CREATE_DEVICE pfnD3D11CreateDevice;
209
210 RTLDRMOD hD3DCompiler;
211 PFN_D3D_DISASSEMBLE pfnD3DDisassemble;
212
213 DXDEVICE device; /* Device for the VMSVGA3D context independent operation. */
214} VMSVGA3DBACKEND;
215
216
217static int dxDeviceFlush(DXDEVICE *pDevice);
218static DECLCALLBACK(void) vmsvga3dBackSurfaceDestroy(PVGASTATECC pThisCC, PVMSVGA3DSURFACE pSurface);
219
220
221DECLINLINE(D3D11_TEXTURECUBE_FACE) vmsvga3dCubemapFaceFromIndex(uint32_t iFace)
222{
223 D3D11_TEXTURECUBE_FACE Face;
224 switch (iFace)
225 {
226 case 0: Face = D3D11_TEXTURECUBE_FACE_POSITIVE_X; break;
227 case 1: Face = D3D11_TEXTURECUBE_FACE_NEGATIVE_X; break;
228 case 2: Face = D3D11_TEXTURECUBE_FACE_POSITIVE_Y; break;
229 case 3: Face = D3D11_TEXTURECUBE_FACE_NEGATIVE_Y; break;
230 case 4: Face = D3D11_TEXTURECUBE_FACE_POSITIVE_Z; break;
231 default:
232 case 5: Face = D3D11_TEXTURECUBE_FACE_NEGATIVE_Z; break;
233 }
234 return Face;
235}
236
237#define DX_REPLACE_X8_WITH_A8
238static DXGI_FORMAT vmsvgaDXSurfaceFormat2Dxgi(SVGA3dSurfaceFormat format)
239{
240 /* Ensure that correct headers are used.
241 * SVGA3D_AYUV was equal to 45, then replaced with SVGA3D_FORMAT_DEAD2 = 45, and redefined as SVGA3D_AYUV = 152.
242 */
243 AssertCompile(SVGA3D_AYUV == 152);
244
245#define DXGI_FORMAT_ DXGI_FORMAT_UNKNOWN
246 /** @todo More formats. */
247 switch (format)
248 {
249#ifdef DX_REPLACE_X8_WITH_A8
250 case SVGA3D_X8R8G8B8: return DXGI_FORMAT_B8G8R8A8_UNORM;
251#else
252 case SVGA3D_X8R8G8B8: return DXGI_FORMAT_B8G8R8X8_UNORM;
253#endif
254 case SVGA3D_A8R8G8B8: return DXGI_FORMAT_B8G8R8A8_UNORM;
255 case SVGA3D_R5G6B5: return DXGI_FORMAT_B5G6R5_UNORM;
256 case SVGA3D_X1R5G5B5: return DXGI_FORMAT_B5G5R5A1_UNORM;
257 case SVGA3D_A1R5G5B5: return DXGI_FORMAT_B5G5R5A1_UNORM;
258 case SVGA3D_A4R4G4B4: break; // 11.1 return DXGI_FORMAT_B4G4R4A4_UNORM;
259 case SVGA3D_Z_D32: break;
260 case SVGA3D_Z_D16: return DXGI_FORMAT_D16_UNORM;
261 case SVGA3D_Z_D24S8: return DXGI_FORMAT_D24_UNORM_S8_UINT;
262 case SVGA3D_Z_D15S1: break;
263 case SVGA3D_LUMINANCE8: return DXGI_FORMAT_;
264 case SVGA3D_LUMINANCE4_ALPHA4: return DXGI_FORMAT_;
265 case SVGA3D_LUMINANCE16: return DXGI_FORMAT_;
266 case SVGA3D_LUMINANCE8_ALPHA8: return DXGI_FORMAT_;
267 case SVGA3D_DXT1: return DXGI_FORMAT_;
268 case SVGA3D_DXT2: return DXGI_FORMAT_;
269 case SVGA3D_DXT3: return DXGI_FORMAT_;
270 case SVGA3D_DXT4: return DXGI_FORMAT_;
271 case SVGA3D_DXT5: return DXGI_FORMAT_;
272 case SVGA3D_BUMPU8V8: return DXGI_FORMAT_;
273 case SVGA3D_BUMPL6V5U5: return DXGI_FORMAT_;
274 case SVGA3D_BUMPX8L8V8U8: return DXGI_FORMAT_;
275 case SVGA3D_FORMAT_DEAD1: break;
276 case SVGA3D_ARGB_S10E5: return DXGI_FORMAT_;
277 case SVGA3D_ARGB_S23E8: return DXGI_FORMAT_;
278 case SVGA3D_A2R10G10B10: return DXGI_FORMAT_;
279 case SVGA3D_V8U8: return DXGI_FORMAT_;
280 case SVGA3D_Q8W8V8U8: return DXGI_FORMAT_;
281 case SVGA3D_CxV8U8: return DXGI_FORMAT_;
282 case SVGA3D_X8L8V8U8: return DXGI_FORMAT_;
283 case SVGA3D_A2W10V10U10: return DXGI_FORMAT_;
284 case SVGA3D_ALPHA8: return DXGI_FORMAT_;
285 case SVGA3D_R_S10E5: return DXGI_FORMAT_;
286 case SVGA3D_R_S23E8: return DXGI_FORMAT_;
287 case SVGA3D_RG_S10E5: return DXGI_FORMAT_;
288 case SVGA3D_RG_S23E8: return DXGI_FORMAT_;
289 case SVGA3D_BUFFER: return DXGI_FORMAT_;
290 case SVGA3D_Z_D24X8: return DXGI_FORMAT_;
291 case SVGA3D_V16U16: return DXGI_FORMAT_;
292 case SVGA3D_G16R16: return DXGI_FORMAT_;
293 case SVGA3D_A16B16G16R16: return DXGI_FORMAT_;
294 case SVGA3D_UYVY: return DXGI_FORMAT_;
295 case SVGA3D_YUY2: return DXGI_FORMAT_;
296 case SVGA3D_NV12: return DXGI_FORMAT_;
297 case SVGA3D_FORMAT_DEAD2: break; /* Old SVGA3D_AYUV */
298 case SVGA3D_R32G32B32A32_TYPELESS: return DXGI_FORMAT_R32G32B32A32_TYPELESS;
299 case SVGA3D_R32G32B32A32_UINT: return DXGI_FORMAT_R32G32B32A32_UINT;
300 case SVGA3D_R32G32B32A32_SINT: return DXGI_FORMAT_R32G32B32A32_SINT;
301 case SVGA3D_R32G32B32_TYPELESS: return DXGI_FORMAT_R32G32B32_TYPELESS;
302 case SVGA3D_R32G32B32_FLOAT: return DXGI_FORMAT_R32G32B32_FLOAT;
303 case SVGA3D_R32G32B32_UINT: return DXGI_FORMAT_R32G32B32_UINT;
304 case SVGA3D_R32G32B32_SINT: return DXGI_FORMAT_R32G32B32_SINT;
305 case SVGA3D_R16G16B16A16_TYPELESS: return DXGI_FORMAT_R16G16B16A16_TYPELESS;
306 case SVGA3D_R16G16B16A16_UINT: return DXGI_FORMAT_R16G16B16A16_UINT;
307 case SVGA3D_R16G16B16A16_SNORM: return DXGI_FORMAT_R16G16B16A16_SNORM;
308 case SVGA3D_R16G16B16A16_SINT: return DXGI_FORMAT_R16G16B16A16_SINT;
309 case SVGA3D_R32G32_TYPELESS: return DXGI_FORMAT_R32G32_TYPELESS;
310 case SVGA3D_R32G32_UINT: return DXGI_FORMAT_R32G32_UINT;
311 case SVGA3D_R32G32_SINT: return DXGI_FORMAT_R32G32_SINT;
312 case SVGA3D_R32G8X24_TYPELESS: return DXGI_FORMAT_R32G8X24_TYPELESS;
313 case SVGA3D_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
314 case SVGA3D_R32_FLOAT_X8X24: return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
315 case SVGA3D_X32_G8X24_UINT: return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
316 case SVGA3D_R10G10B10A2_TYPELESS: return DXGI_FORMAT_R10G10B10A2_TYPELESS;
317 case SVGA3D_R10G10B10A2_UINT: return DXGI_FORMAT_R10G10B10A2_UINT;
318 case SVGA3D_R11G11B10_FLOAT: return DXGI_FORMAT_R11G11B10_FLOAT;
319 case SVGA3D_R8G8B8A8_TYPELESS: return DXGI_FORMAT_R8G8B8A8_TYPELESS;
320 case SVGA3D_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM;
321 case SVGA3D_R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
322 case SVGA3D_R8G8B8A8_UINT: return DXGI_FORMAT_R8G8B8A8_UINT;
323 case SVGA3D_R8G8B8A8_SINT: return DXGI_FORMAT_R8G8B8A8_SINT;
324 case SVGA3D_R16G16_TYPELESS: return DXGI_FORMAT_R16G16_TYPELESS;
325 case SVGA3D_R16G16_UINT: return DXGI_FORMAT_R16G16_UINT;
326 case SVGA3D_R16G16_SINT: return DXGI_FORMAT_R16G16_SINT;
327 case SVGA3D_R32_TYPELESS: return DXGI_FORMAT_R32_TYPELESS;
328 case SVGA3D_D32_FLOAT: return DXGI_FORMAT_D32_FLOAT;
329 case SVGA3D_R32_UINT: return DXGI_FORMAT_R32_UINT;
330 case SVGA3D_R32_SINT: return DXGI_FORMAT_R32_SINT;
331 case SVGA3D_R24G8_TYPELESS: return DXGI_FORMAT_R24G8_TYPELESS;
332 case SVGA3D_D24_UNORM_S8_UINT: return DXGI_FORMAT_D24_UNORM_S8_UINT;
333 case SVGA3D_R24_UNORM_X8: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
334 case SVGA3D_X24_G8_UINT: return DXGI_FORMAT_X24_TYPELESS_G8_UINT;
335 case SVGA3D_R8G8_TYPELESS: return DXGI_FORMAT_R8G8_TYPELESS;
336 case SVGA3D_R8G8_UNORM: return DXGI_FORMAT_R8G8_UNORM;
337 case SVGA3D_R8G8_UINT: return DXGI_FORMAT_R8G8_UINT;
338 case SVGA3D_R8G8_SINT: return DXGI_FORMAT_R8G8_SINT;
339 case SVGA3D_R16_TYPELESS: return DXGI_FORMAT_R16_TYPELESS;
340 case SVGA3D_R16_UNORM: return DXGI_FORMAT_R16_UNORM;
341 case SVGA3D_R16_UINT: return DXGI_FORMAT_R16_UINT;
342 case SVGA3D_R16_SNORM: return DXGI_FORMAT_R16_SNORM;
343 case SVGA3D_R16_SINT: return DXGI_FORMAT_R16_SINT;
344 case SVGA3D_R8_TYPELESS: return DXGI_FORMAT_R8_TYPELESS;
345 case SVGA3D_R8_UNORM: return DXGI_FORMAT_R8_UNORM;
346 case SVGA3D_R8_UINT: return DXGI_FORMAT_R8_UINT;
347 case SVGA3D_R8_SNORM: return DXGI_FORMAT_R8_SNORM;
348 case SVGA3D_R8_SINT: return DXGI_FORMAT_R8_SINT;
349 case SVGA3D_P8: break;
350 case SVGA3D_R9G9B9E5_SHAREDEXP: return DXGI_FORMAT_R9G9B9E5_SHAREDEXP;
351 case SVGA3D_R8G8_B8G8_UNORM: return DXGI_FORMAT_R8G8_B8G8_UNORM;
352 case SVGA3D_G8R8_G8B8_UNORM: return DXGI_FORMAT_G8R8_G8B8_UNORM;
353 case SVGA3D_BC1_TYPELESS: return DXGI_FORMAT_BC1_TYPELESS;
354 case SVGA3D_BC1_UNORM_SRGB: return DXGI_FORMAT_BC1_UNORM_SRGB;
355 case SVGA3D_BC2_TYPELESS: return DXGI_FORMAT_BC2_TYPELESS;
356 case SVGA3D_BC2_UNORM_SRGB: return DXGI_FORMAT_BC2_UNORM_SRGB;
357 case SVGA3D_BC3_TYPELESS: return DXGI_FORMAT_BC3_TYPELESS;
358 case SVGA3D_BC3_UNORM_SRGB: return DXGI_FORMAT_BC3_UNORM_SRGB;
359 case SVGA3D_BC4_TYPELESS: return DXGI_FORMAT_BC4_TYPELESS;
360 case SVGA3D_ATI1: break;
361 case SVGA3D_BC4_SNORM: return DXGI_FORMAT_BC4_SNORM;
362 case SVGA3D_BC5_TYPELESS: return DXGI_FORMAT_BC5_TYPELESS;
363 case SVGA3D_ATI2: break;
364 case SVGA3D_BC5_SNORM: return DXGI_FORMAT_BC5_SNORM;
365 case SVGA3D_R10G10B10_XR_BIAS_A2_UNORM: return DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM;
366 case SVGA3D_B8G8R8A8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_TYPELESS;
367 case SVGA3D_B8G8R8A8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
368#ifdef DX_REPLACE_X8_WITH_A8
369 case SVGA3D_B8G8R8X8_TYPELESS: return DXGI_FORMAT_B8G8R8A8_TYPELESS;
370 case SVGA3D_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
371#else
372 case SVGA3D_B8G8R8X8_TYPELESS: return DXGI_FORMAT_B8G8R8X8_TYPELESS;
373 case SVGA3D_B8G8R8X8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
374#endif
375 case SVGA3D_Z_DF16: break;
376 case SVGA3D_Z_DF24: break;
377 case SVGA3D_Z_D24S8_INT: return DXGI_FORMAT_D24_UNORM_S8_UINT;
378 case SVGA3D_YV12: break;
379 case SVGA3D_R32G32B32A32_FLOAT: return DXGI_FORMAT_R32G32B32A32_FLOAT;
380 case SVGA3D_R16G16B16A16_FLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT;
381 case SVGA3D_R16G16B16A16_UNORM: return DXGI_FORMAT_R16G16B16A16_UNORM;
382 case SVGA3D_R32G32_FLOAT: return DXGI_FORMAT_R32G32_FLOAT;
383 case SVGA3D_R10G10B10A2_UNORM: return DXGI_FORMAT_R10G10B10A2_UNORM;
384 case SVGA3D_R8G8B8A8_SNORM: return DXGI_FORMAT_R8G8B8A8_SNORM;
385 case SVGA3D_R16G16_FLOAT: return DXGI_FORMAT_R16G16_FLOAT;
386 case SVGA3D_R16G16_UNORM: return DXGI_FORMAT_R16G16_UNORM;
387 case SVGA3D_R16G16_SNORM: return DXGI_FORMAT_R16G16_SNORM;
388 case SVGA3D_R32_FLOAT: return DXGI_FORMAT_R32_FLOAT;
389 case SVGA3D_R8G8_SNORM: return DXGI_FORMAT_R8G8_SNORM;
390 case SVGA3D_R16_FLOAT: return DXGI_FORMAT_R16_FLOAT;
391 case SVGA3D_D16_UNORM: return DXGI_FORMAT_D16_UNORM;
392 case SVGA3D_A8_UNORM: return DXGI_FORMAT_A8_UNORM;
393 case SVGA3D_BC1_UNORM: return DXGI_FORMAT_BC1_UNORM;
394 case SVGA3D_BC2_UNORM: return DXGI_FORMAT_BC2_UNORM;
395 case SVGA3D_BC3_UNORM: return DXGI_FORMAT_BC3_UNORM;
396 case SVGA3D_B5G6R5_UNORM: return DXGI_FORMAT_B5G6R5_UNORM;
397 case SVGA3D_B5G5R5A1_UNORM: return DXGI_FORMAT_B5G5R5A1_UNORM;
398 case SVGA3D_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM;
399#ifdef DX_REPLACE_X8_WITH_A8
400 case SVGA3D_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM;
401#else
402 case SVGA3D_B8G8R8X8_UNORM: return DXGI_FORMAT_B8G8R8X8_UNORM;
403#endif
404 case SVGA3D_BC4_UNORM: return DXGI_FORMAT_BC4_UNORM;
405 case SVGA3D_BC5_UNORM: return DXGI_FORMAT_BC5_UNORM;
406
407 case SVGA3D_B4G4R4A4_UNORM: return DXGI_FORMAT_;
408 case SVGA3D_BC6H_TYPELESS: return DXGI_FORMAT_;
409 case SVGA3D_BC6H_UF16: return DXGI_FORMAT_;
410 case SVGA3D_BC6H_SF16: return DXGI_FORMAT_;
411 case SVGA3D_BC7_TYPELESS: return DXGI_FORMAT_;
412 case SVGA3D_BC7_UNORM: return DXGI_FORMAT_;
413 case SVGA3D_BC7_UNORM_SRGB: return DXGI_FORMAT_;
414 case SVGA3D_AYUV: return DXGI_FORMAT_;
415
416 case SVGA3D_FORMAT_INVALID:
417 case SVGA3D_FORMAT_MAX: break;
418 }
419 // AssertFailed();
420 return DXGI_FORMAT_UNKNOWN;
421#undef DXGI_FORMAT_
422}
423
424
425static SVGA3dSurfaceFormat vmsvgaDXDevCapSurfaceFmt2Format(SVGA3dDevCapIndex enmDevCap)
426{
427 switch (enmDevCap)
428 {
429 case SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8: return SVGA3D_X8R8G8B8;
430 case SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8: return SVGA3D_A8R8G8B8;
431 case SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10: return SVGA3D_A2R10G10B10;
432 case SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5: return SVGA3D_X1R5G5B5;
433 case SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5: return SVGA3D_A1R5G5B5;
434 case SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4: return SVGA3D_A4R4G4B4;
435 case SVGA3D_DEVCAP_SURFACEFMT_R5G6B5: return SVGA3D_R5G6B5;
436 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16: return SVGA3D_LUMINANCE16;
437 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8: return SVGA3D_LUMINANCE8_ALPHA8;
438 case SVGA3D_DEVCAP_SURFACEFMT_ALPHA8: return SVGA3D_ALPHA8;
439 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8: return SVGA3D_LUMINANCE8;
440 case SVGA3D_DEVCAP_SURFACEFMT_Z_D16: return SVGA3D_Z_D16;
441 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8: return SVGA3D_Z_D24S8;
442 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8: return SVGA3D_Z_D24X8;
443 case SVGA3D_DEVCAP_SURFACEFMT_DXT1: return SVGA3D_DXT1;
444 case SVGA3D_DEVCAP_SURFACEFMT_DXT2: return SVGA3D_DXT2;
445 case SVGA3D_DEVCAP_SURFACEFMT_DXT3: return SVGA3D_DXT3;
446 case SVGA3D_DEVCAP_SURFACEFMT_DXT4: return SVGA3D_DXT4;
447 case SVGA3D_DEVCAP_SURFACEFMT_DXT5: return SVGA3D_DXT5;
448 case SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8: return SVGA3D_BUMPX8L8V8U8;
449 case SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10: return SVGA3D_A2W10V10U10;
450 case SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8: return SVGA3D_BUMPU8V8;
451 case SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8: return SVGA3D_Q8W8V8U8;
452 case SVGA3D_DEVCAP_SURFACEFMT_CxV8U8: return SVGA3D_CxV8U8;
453 case SVGA3D_DEVCAP_SURFACEFMT_R_S10E5: return SVGA3D_R_S10E5;
454 case SVGA3D_DEVCAP_SURFACEFMT_R_S23E8: return SVGA3D_R_S23E8;
455 case SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5: return SVGA3D_RG_S10E5;
456 case SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8: return SVGA3D_RG_S23E8;
457 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5: return SVGA3D_ARGB_S10E5;
458 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8: return SVGA3D_ARGB_S23E8;
459 case SVGA3D_DEVCAP_SURFACEFMT_V16U16: return SVGA3D_V16U16;
460 case SVGA3D_DEVCAP_SURFACEFMT_G16R16: return SVGA3D_G16R16;
461 case SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16: return SVGA3D_A16B16G16R16;
462 case SVGA3D_DEVCAP_SURFACEFMT_UYVY: return SVGA3D_UYVY;
463 case SVGA3D_DEVCAP_SURFACEFMT_YUY2: return SVGA3D_YUY2;
464 case SVGA3D_DEVCAP_SURFACEFMT_NV12: return SVGA3D_NV12;
465 case SVGA3D_DEVCAP_DEAD10: return SVGA3D_FORMAT_DEAD2; /* SVGA3D_DEVCAP_SURFACEFMT_AYUV -> SVGA3D_AYUV */
466 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF16: return SVGA3D_Z_DF16;
467 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF24: return SVGA3D_Z_DF24;
468 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT: return SVGA3D_Z_D24S8_INT;
469 case SVGA3D_DEVCAP_SURFACEFMT_ATI1: return SVGA3D_ATI1;
470 case SVGA3D_DEVCAP_SURFACEFMT_ATI2: return SVGA3D_ATI2;
471 case SVGA3D_DEVCAP_SURFACEFMT_YV12: return SVGA3D_YV12;
472 default:
473 AssertFailed();
474 break;
475 }
476 return SVGA3D_FORMAT_INVALID;
477}
478
479
480static SVGA3dSurfaceFormat vmsvgaDXDevCapDxfmt2Format(SVGA3dDevCapIndex enmDevCap)
481{
482 switch (enmDevCap)
483 {
484 case SVGA3D_DEVCAP_DXFMT_X8R8G8B8: return SVGA3D_X8R8G8B8;
485 case SVGA3D_DEVCAP_DXFMT_A8R8G8B8: return SVGA3D_A8R8G8B8;
486 case SVGA3D_DEVCAP_DXFMT_R5G6B5: return SVGA3D_R5G6B5;
487 case SVGA3D_DEVCAP_DXFMT_X1R5G5B5: return SVGA3D_X1R5G5B5;
488 case SVGA3D_DEVCAP_DXFMT_A1R5G5B5: return SVGA3D_A1R5G5B5;
489 case SVGA3D_DEVCAP_DXFMT_A4R4G4B4: return SVGA3D_A4R4G4B4;
490 case SVGA3D_DEVCAP_DXFMT_Z_D32: return SVGA3D_Z_D32;
491 case SVGA3D_DEVCAP_DXFMT_Z_D16: return SVGA3D_Z_D16;
492 case SVGA3D_DEVCAP_DXFMT_Z_D24S8: return SVGA3D_Z_D24S8;
493 case SVGA3D_DEVCAP_DXFMT_Z_D15S1: return SVGA3D_Z_D15S1;
494 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8: return SVGA3D_LUMINANCE8;
495 case SVGA3D_DEVCAP_DXFMT_LUMINANCE4_ALPHA4: return SVGA3D_LUMINANCE4_ALPHA4;
496 case SVGA3D_DEVCAP_DXFMT_LUMINANCE16: return SVGA3D_LUMINANCE16;
497 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8_ALPHA8: return SVGA3D_LUMINANCE8_ALPHA8;
498 case SVGA3D_DEVCAP_DXFMT_DXT1: return SVGA3D_DXT1;
499 case SVGA3D_DEVCAP_DXFMT_DXT2: return SVGA3D_DXT2;
500 case SVGA3D_DEVCAP_DXFMT_DXT3: return SVGA3D_DXT3;
501 case SVGA3D_DEVCAP_DXFMT_DXT4: return SVGA3D_DXT4;
502 case SVGA3D_DEVCAP_DXFMT_DXT5: return SVGA3D_DXT5;
503 case SVGA3D_DEVCAP_DXFMT_BUMPU8V8: return SVGA3D_BUMPU8V8;
504 case SVGA3D_DEVCAP_DXFMT_BUMPL6V5U5: return SVGA3D_BUMPL6V5U5;
505 case SVGA3D_DEVCAP_DXFMT_BUMPX8L8V8U8: return SVGA3D_BUMPX8L8V8U8;
506 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD1: return SVGA3D_FORMAT_DEAD1;
507 case SVGA3D_DEVCAP_DXFMT_ARGB_S10E5: return SVGA3D_ARGB_S10E5;
508 case SVGA3D_DEVCAP_DXFMT_ARGB_S23E8: return SVGA3D_ARGB_S23E8;
509 case SVGA3D_DEVCAP_DXFMT_A2R10G10B10: return SVGA3D_A2R10G10B10;
510 case SVGA3D_DEVCAP_DXFMT_V8U8: return SVGA3D_V8U8;
511 case SVGA3D_DEVCAP_DXFMT_Q8W8V8U8: return SVGA3D_Q8W8V8U8;
512 case SVGA3D_DEVCAP_DXFMT_CxV8U8: return SVGA3D_CxV8U8;
513 case SVGA3D_DEVCAP_DXFMT_X8L8V8U8: return SVGA3D_X8L8V8U8;
514 case SVGA3D_DEVCAP_DXFMT_A2W10V10U10: return SVGA3D_A2W10V10U10;
515 case SVGA3D_DEVCAP_DXFMT_ALPHA8: return SVGA3D_ALPHA8;
516 case SVGA3D_DEVCAP_DXFMT_R_S10E5: return SVGA3D_R_S10E5;
517 case SVGA3D_DEVCAP_DXFMT_R_S23E8: return SVGA3D_R_S23E8;
518 case SVGA3D_DEVCAP_DXFMT_RG_S10E5: return SVGA3D_RG_S10E5;
519 case SVGA3D_DEVCAP_DXFMT_RG_S23E8: return SVGA3D_RG_S23E8;
520 case SVGA3D_DEVCAP_DXFMT_BUFFER: return SVGA3D_BUFFER;
521 case SVGA3D_DEVCAP_DXFMT_Z_D24X8: return SVGA3D_Z_D24X8;
522 case SVGA3D_DEVCAP_DXFMT_V16U16: return SVGA3D_V16U16;
523 case SVGA3D_DEVCAP_DXFMT_G16R16: return SVGA3D_G16R16;
524 case SVGA3D_DEVCAP_DXFMT_A16B16G16R16: return SVGA3D_A16B16G16R16;
525 case SVGA3D_DEVCAP_DXFMT_UYVY: return SVGA3D_UYVY;
526 case SVGA3D_DEVCAP_DXFMT_YUY2: return SVGA3D_YUY2;
527 case SVGA3D_DEVCAP_DXFMT_NV12: return SVGA3D_NV12;
528 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD2: return SVGA3D_FORMAT_DEAD2; /* SVGA3D_DEVCAP_DXFMT_AYUV -> SVGA3D_AYUV */
529 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_TYPELESS: return SVGA3D_R32G32B32A32_TYPELESS;
530 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_UINT: return SVGA3D_R32G32B32A32_UINT;
531 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_SINT: return SVGA3D_R32G32B32A32_SINT;
532 case SVGA3D_DEVCAP_DXFMT_R32G32B32_TYPELESS: return SVGA3D_R32G32B32_TYPELESS;
533 case SVGA3D_DEVCAP_DXFMT_R32G32B32_FLOAT: return SVGA3D_R32G32B32_FLOAT;
534 case SVGA3D_DEVCAP_DXFMT_R32G32B32_UINT: return SVGA3D_R32G32B32_UINT;
535 case SVGA3D_DEVCAP_DXFMT_R32G32B32_SINT: return SVGA3D_R32G32B32_SINT;
536 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_TYPELESS: return SVGA3D_R16G16B16A16_TYPELESS;
537 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UINT: return SVGA3D_R16G16B16A16_UINT;
538 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SNORM: return SVGA3D_R16G16B16A16_SNORM;
539 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SINT: return SVGA3D_R16G16B16A16_SINT;
540 case SVGA3D_DEVCAP_DXFMT_R32G32_TYPELESS: return SVGA3D_R32G32_TYPELESS;
541 case SVGA3D_DEVCAP_DXFMT_R32G32_UINT: return SVGA3D_R32G32_UINT;
542 case SVGA3D_DEVCAP_DXFMT_R32G32_SINT: return SVGA3D_R32G32_SINT;
543 case SVGA3D_DEVCAP_DXFMT_R32G8X24_TYPELESS: return SVGA3D_R32G8X24_TYPELESS;
544 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT_S8X24_UINT: return SVGA3D_D32_FLOAT_S8X24_UINT;
545 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT_X8X24: return SVGA3D_R32_FLOAT_X8X24;
546 case SVGA3D_DEVCAP_DXFMT_X32_G8X24_UINT: return SVGA3D_X32_G8X24_UINT;
547 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_TYPELESS: return SVGA3D_R10G10B10A2_TYPELESS;
548 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UINT: return SVGA3D_R10G10B10A2_UINT;
549 case SVGA3D_DEVCAP_DXFMT_R11G11B10_FLOAT: return SVGA3D_R11G11B10_FLOAT;
550 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_TYPELESS: return SVGA3D_R8G8B8A8_TYPELESS;
551 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM: return SVGA3D_R8G8B8A8_UNORM;
552 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM_SRGB: return SVGA3D_R8G8B8A8_UNORM_SRGB;
553 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UINT: return SVGA3D_R8G8B8A8_UINT;
554 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SINT: return SVGA3D_R8G8B8A8_SINT;
555 case SVGA3D_DEVCAP_DXFMT_R16G16_TYPELESS: return SVGA3D_R16G16_TYPELESS;
556 case SVGA3D_DEVCAP_DXFMT_R16G16_UINT: return SVGA3D_R16G16_UINT;
557 case SVGA3D_DEVCAP_DXFMT_R16G16_SINT: return SVGA3D_R16G16_SINT;
558 case SVGA3D_DEVCAP_DXFMT_R32_TYPELESS: return SVGA3D_R32_TYPELESS;
559 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT: return SVGA3D_D32_FLOAT;
560 case SVGA3D_DEVCAP_DXFMT_R32_UINT: return SVGA3D_R32_UINT;
561 case SVGA3D_DEVCAP_DXFMT_R32_SINT: return SVGA3D_R32_SINT;
562 case SVGA3D_DEVCAP_DXFMT_R24G8_TYPELESS: return SVGA3D_R24G8_TYPELESS;
563 case SVGA3D_DEVCAP_DXFMT_D24_UNORM_S8_UINT: return SVGA3D_D24_UNORM_S8_UINT;
564 case SVGA3D_DEVCAP_DXFMT_R24_UNORM_X8: return SVGA3D_R24_UNORM_X8;
565 case SVGA3D_DEVCAP_DXFMT_X24_G8_UINT: return SVGA3D_X24_G8_UINT;
566 case SVGA3D_DEVCAP_DXFMT_R8G8_TYPELESS: return SVGA3D_R8G8_TYPELESS;
567 case SVGA3D_DEVCAP_DXFMT_R8G8_UNORM: return SVGA3D_R8G8_UNORM;
568 case SVGA3D_DEVCAP_DXFMT_R8G8_UINT: return SVGA3D_R8G8_UINT;
569 case SVGA3D_DEVCAP_DXFMT_R8G8_SINT: return SVGA3D_R8G8_SINT;
570 case SVGA3D_DEVCAP_DXFMT_R16_TYPELESS: return SVGA3D_R16_TYPELESS;
571 case SVGA3D_DEVCAP_DXFMT_R16_UNORM: return SVGA3D_R16_UNORM;
572 case SVGA3D_DEVCAP_DXFMT_R16_UINT: return SVGA3D_R16_UINT;
573 case SVGA3D_DEVCAP_DXFMT_R16_SNORM: return SVGA3D_R16_SNORM;
574 case SVGA3D_DEVCAP_DXFMT_R16_SINT: return SVGA3D_R16_SINT;
575 case SVGA3D_DEVCAP_DXFMT_R8_TYPELESS: return SVGA3D_R8_TYPELESS;
576 case SVGA3D_DEVCAP_DXFMT_R8_UNORM: return SVGA3D_R8_UNORM;
577 case SVGA3D_DEVCAP_DXFMT_R8_UINT: return SVGA3D_R8_UINT;
578 case SVGA3D_DEVCAP_DXFMT_R8_SNORM: return SVGA3D_R8_SNORM;
579 case SVGA3D_DEVCAP_DXFMT_R8_SINT: return SVGA3D_R8_SINT;
580 case SVGA3D_DEVCAP_DXFMT_P8: return SVGA3D_P8;
581 case SVGA3D_DEVCAP_DXFMT_R9G9B9E5_SHAREDEXP: return SVGA3D_R9G9B9E5_SHAREDEXP;
582 case SVGA3D_DEVCAP_DXFMT_R8G8_B8G8_UNORM: return SVGA3D_R8G8_B8G8_UNORM;
583 case SVGA3D_DEVCAP_DXFMT_G8R8_G8B8_UNORM: return SVGA3D_G8R8_G8B8_UNORM;
584 case SVGA3D_DEVCAP_DXFMT_BC1_TYPELESS: return SVGA3D_BC1_TYPELESS;
585 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM_SRGB: return SVGA3D_BC1_UNORM_SRGB;
586 case SVGA3D_DEVCAP_DXFMT_BC2_TYPELESS: return SVGA3D_BC2_TYPELESS;
587 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM_SRGB: return SVGA3D_BC2_UNORM_SRGB;
588 case SVGA3D_DEVCAP_DXFMT_BC3_TYPELESS: return SVGA3D_BC3_TYPELESS;
589 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM_SRGB: return SVGA3D_BC3_UNORM_SRGB;
590 case SVGA3D_DEVCAP_DXFMT_BC4_TYPELESS: return SVGA3D_BC4_TYPELESS;
591 case SVGA3D_DEVCAP_DXFMT_ATI1: return SVGA3D_ATI1;
592 case SVGA3D_DEVCAP_DXFMT_BC4_SNORM: return SVGA3D_BC4_SNORM;
593 case SVGA3D_DEVCAP_DXFMT_BC5_TYPELESS: return SVGA3D_BC5_TYPELESS;
594 case SVGA3D_DEVCAP_DXFMT_ATI2: return SVGA3D_ATI2;
595 case SVGA3D_DEVCAP_DXFMT_BC5_SNORM: return SVGA3D_BC5_SNORM;
596 case SVGA3D_DEVCAP_DXFMT_R10G10B10_XR_BIAS_A2_UNORM: return SVGA3D_R10G10B10_XR_BIAS_A2_UNORM;
597 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_TYPELESS: return SVGA3D_B8G8R8A8_TYPELESS;
598 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM_SRGB: return SVGA3D_B8G8R8A8_UNORM_SRGB;
599 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_TYPELESS: return SVGA3D_B8G8R8X8_TYPELESS;
600 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM_SRGB: return SVGA3D_B8G8R8X8_UNORM_SRGB;
601 case SVGA3D_DEVCAP_DXFMT_Z_DF16: return SVGA3D_Z_DF16;
602 case SVGA3D_DEVCAP_DXFMT_Z_DF24: return SVGA3D_Z_DF24;
603 case SVGA3D_DEVCAP_DXFMT_Z_D24S8_INT: return SVGA3D_Z_D24S8_INT;
604 case SVGA3D_DEVCAP_DXFMT_YV12: return SVGA3D_YV12;
605 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_FLOAT: return SVGA3D_R32G32B32A32_FLOAT;
606 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_FLOAT: return SVGA3D_R16G16B16A16_FLOAT;
607 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UNORM: return SVGA3D_R16G16B16A16_UNORM;
608 case SVGA3D_DEVCAP_DXFMT_R32G32_FLOAT: return SVGA3D_R32G32_FLOAT;
609 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UNORM: return SVGA3D_R10G10B10A2_UNORM;
610 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SNORM: return SVGA3D_R8G8B8A8_SNORM;
611 case SVGA3D_DEVCAP_DXFMT_R16G16_FLOAT: return SVGA3D_R16G16_FLOAT;
612 case SVGA3D_DEVCAP_DXFMT_R16G16_UNORM: return SVGA3D_R16G16_UNORM;
613 case SVGA3D_DEVCAP_DXFMT_R16G16_SNORM: return SVGA3D_R16G16_SNORM;
614 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT: return SVGA3D_R32_FLOAT;
615 case SVGA3D_DEVCAP_DXFMT_R8G8_SNORM: return SVGA3D_R8G8_SNORM;
616 case SVGA3D_DEVCAP_DXFMT_R16_FLOAT: return SVGA3D_R16_FLOAT;
617 case SVGA3D_DEVCAP_DXFMT_D16_UNORM: return SVGA3D_D16_UNORM;
618 case SVGA3D_DEVCAP_DXFMT_A8_UNORM: return SVGA3D_A8_UNORM;
619 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM: return SVGA3D_BC1_UNORM;
620 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM: return SVGA3D_BC2_UNORM;
621 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM: return SVGA3D_BC3_UNORM;
622 case SVGA3D_DEVCAP_DXFMT_B5G6R5_UNORM: return SVGA3D_B5G6R5_UNORM;
623 case SVGA3D_DEVCAP_DXFMT_B5G5R5A1_UNORM: return SVGA3D_B5G5R5A1_UNORM;
624 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM: return SVGA3D_B8G8R8A8_UNORM;
625 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM: return SVGA3D_B8G8R8X8_UNORM;
626 case SVGA3D_DEVCAP_DXFMT_BC4_UNORM: return SVGA3D_BC4_UNORM;
627 case SVGA3D_DEVCAP_DXFMT_BC5_UNORM: return SVGA3D_BC5_UNORM;
628 case SVGA3D_DEVCAP_DXFMT_BC6H_TYPELESS: return SVGA3D_BC6H_TYPELESS;
629 case SVGA3D_DEVCAP_DXFMT_BC6H_UF16: return SVGA3D_BC6H_UF16;
630 case SVGA3D_DEVCAP_DXFMT_BC6H_SF16: return SVGA3D_BC6H_SF16;
631 case SVGA3D_DEVCAP_DXFMT_BC7_TYPELESS: return SVGA3D_BC7_TYPELESS;
632 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM: return SVGA3D_BC7_UNORM;
633 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM_SRGB: return SVGA3D_BC7_UNORM_SRGB;
634 default:
635 AssertFailed();
636 break;
637 }
638 return SVGA3D_FORMAT_INVALID;
639}
640
641
642static int vmsvgaDXCheckFormatSupportPreDX(PVMSVGA3DSTATE pState, SVGA3dSurfaceFormat enmFormat, uint32_t *pu32DevCap)
643{
644 int rc = VINF_SUCCESS;
645
646 *pu32DevCap = 0;
647
648 DXGI_FORMAT const dxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(enmFormat);
649 if (dxgiFormat != DXGI_FORMAT_UNKNOWN)
650 {
651 RT_NOREF(pState);
652 /** @todo Implement */
653 }
654 else
655 rc = VERR_NOT_SUPPORTED;
656 return rc;
657}
658
659static int vmsvgaDXCheckFormatSupport(PVMSVGA3DSTATE pState, SVGA3dSurfaceFormat enmFormat, uint32_t *pu32DevCap)
660{
661 int rc = VINF_SUCCESS;
662
663 *pu32DevCap = 0;
664
665 DXGI_FORMAT const dxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(enmFormat);
666 if (dxgiFormat != DXGI_FORMAT_UNKNOWN)
667 {
668 ID3D11Device *pDevice = pState->pBackend->device.pDevice;
669 UINT FormatSupport = 0;
670 HRESULT hr = pDevice->CheckFormatSupport(dxgiFormat, &FormatSupport);
671 if (SUCCEEDED(hr))
672 {
673 *pu32DevCap |= SVGA3D_DXFMT_SUPPORTED;
674
675 if (FormatSupport & D3D11_FORMAT_SUPPORT_SHADER_SAMPLE)
676 *pu32DevCap |= SVGA3D_DXFMT_SHADER_SAMPLE;
677
678 if (FormatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)
679 *pu32DevCap |= SVGA3D_DXFMT_COLOR_RENDERTARGET;
680
681 if (FormatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL)
682 *pu32DevCap |= SVGA3D_DXFMT_DEPTH_RENDERTARGET;
683
684 if (FormatSupport & D3D11_FORMAT_SUPPORT_BLENDABLE)
685 *pu32DevCap |= SVGA3D_DXFMT_BLENDABLE;
686
687 if (FormatSupport & D3D11_FORMAT_SUPPORT_MIP)
688 *pu32DevCap |= SVGA3D_DXFMT_MIPS;
689
690 if (FormatSupport & D3D11_FORMAT_SUPPORT_TEXTURECUBE)
691 *pu32DevCap |= SVGA3D_DXFMT_ARRAY;
692
693 if (FormatSupport & D3D11_FORMAT_SUPPORT_TEXTURE3D)
694 *pu32DevCap |= SVGA3D_DXFMT_VOLUME;
695
696 if (FormatSupport & D3D11_FORMAT_SUPPORT_IA_VERTEX_BUFFER)
697 *pu32DevCap |= SVGA3D_DXFMT_DX_VERTEX_BUFFER;
698
699 UINT NumQualityLevels;
700 hr = pDevice->CheckMultisampleQualityLevels(dxgiFormat, 2, &NumQualityLevels);
701 if (SUCCEEDED(hr) && NumQualityLevels != 0)
702 *pu32DevCap |= SVGA3D_DXFMT_MULTISAMPLE;
703 }
704 else
705 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
706 }
707 else
708 rc = VERR_NOT_SUPPORTED;
709 return rc;
710}
711
712
713static int dxDeviceCreate(PVMSVGA3DBACKEND pBackend, DXDEVICE *pDevice)
714{
715 int rc = VINF_SUCCESS;
716
717 IDXGIAdapter *pAdapter = NULL; /* Default adapter. */
718 static D3D_FEATURE_LEVEL const s_aFeatureLevels[] =
719 {
720 /// @todo Requires a Windows 8+ _SDKS: D3D_FEATURE_LEVEL_11_1,
721 D3D_FEATURE_LEVEL_11_0
722 };
723 UINT Flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
724#ifdef DEBUG
725 Flags |= D3D11_CREATE_DEVICE_DEBUG;
726#endif
727
728 HRESULT hr = pBackend->pfnD3D11CreateDevice(pAdapter,
729 D3D_DRIVER_TYPE_HARDWARE,
730 NULL,
731 Flags,
732 s_aFeatureLevels,
733 RT_ELEMENTS(s_aFeatureLevels),
734 D3D11_SDK_VERSION,
735 &pDevice->pDevice,
736 &pDevice->FeatureLevel,
737 &pDevice->pImmediateContext);
738 if (SUCCEEDED(hr))
739 {
740 LogRel(("VMSVGA: Feature level %#x\n", pDevice->FeatureLevel));
741
742#ifdef DEBUG
743 /* Break into debugger when DX runtime detects anything unusual. */
744 HRESULT hr2;
745 ID3D11Debug *pDebug = 0;
746 hr2 = pDevice->pDevice->QueryInterface(__uuidof(ID3D11Debug), (void**)&pDebug);
747 if (SUCCEEDED(hr2))
748 {
749 ID3D11InfoQueue *pInfoQueue = 0;
750 hr2 = pDebug->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&pInfoQueue);
751 if (SUCCEEDED(hr2))
752 {
753 pInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
754 pInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true);
755 pInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING, true);
756
757 /* No breakpoints for the following messages. */
758 D3D11_MESSAGE_ID saIgnoredMessageIds[] =
759 {
760 /* Message ID: Caused by: */
761 D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_TYPE_MISMATCH, /* Autogenerated input signatures. */
762 D3D11_MESSAGE_ID_LIVE_DEVICE, /* Live object report. Does not seem to prevent a breakpoint. */
763 (D3D11_MESSAGE_ID)3146081 /*DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET*/, /* U. */
764 D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_NOT_SET, /* U. */
765 D3D11_MESSAGE_ID_DEVICE_DRAW_SAMPLER_MISMATCH, /* U. */
766 D3D11_MESSAGE_ID_CREATEINPUTLAYOUT_EMPTY_LAYOUT, /* P. */
767 };
768
769 D3D11_INFO_QUEUE_FILTER filter;
770 RT_ZERO(filter);
771 filter.DenyList.NumIDs = RT_ELEMENTS(saIgnoredMessageIds);
772 filter.DenyList.pIDList = saIgnoredMessageIds;
773 pInfoQueue->AddStorageFilterEntries(&filter);
774
775 D3D_RELEASE(pInfoQueue);
776 }
777 D3D_RELEASE(pDebug);
778 }
779#endif
780
781 IDXGIDevice *pDxgiDevice = 0;
782 hr = pDevice->pDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&pDxgiDevice);
783 if (SUCCEEDED(hr))
784 {
785 IDXGIAdapter *pDxgiAdapter = 0;
786 hr = pDxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&pDxgiAdapter);
787 if (SUCCEEDED(hr))
788 {
789 hr = pDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&pDevice->pDxgiFactory);
790 D3D_RELEASE(pDxgiAdapter);
791 }
792
793 D3D_RELEASE(pDxgiDevice);
794 }
795 }
796
797 if (FAILED(hr))
798 rc = VERR_NOT_SUPPORTED;
799
800 return rc;
801}
802
803
804static void dxDeviceDestroy(PVMSVGA3DBACKEND pBackend, DXDEVICE *pDevice)
805{
806 RT_NOREF(pBackend);
807
808 if (pDevice->pImmediateContext)
809 {
810 dxDeviceFlush(pDevice); /* Make sure that any pending draw calls are finished. */
811 pDevice->pImmediateContext->ClearState();
812 }
813
814 D3D_RELEASE(pDevice->pStagingBuffer);
815
816 D3D_RELEASE(pDevice->pDxgiFactory);
817 D3D_RELEASE(pDevice->pImmediateContext);
818
819#ifdef DEBUG
820 HRESULT hr2;
821 ID3D11Debug *pDebug = 0;
822 hr2 = pDevice->pDevice->QueryInterface(__uuidof(ID3D11Debug), (void**)&pDebug);
823 if (SUCCEEDED(hr2))
824 {
825 //pDebug->ReportLiveDeviceObjects(D3D11_RLDO_DETAIL | (D3D11_RLDO_FLAGS)0x4 /*D3D11_RLDO_IGNORE_INTERNAL*/);
826 D3D_RELEASE(pDebug);
827 }
828#endif
829
830 D3D_RELEASE(pDevice->pDevice);
831 RT_ZERO(*pDevice);
832}
833
834
835DECLINLINE(bool) dxIsSurfaceShareable(PVMSVGA3DSURFACE pSurface)
836{
837 /* It is not expected that volume textures will be shared between contexts. */
838 if (pSurface->surfaceFlags & SVGA3D_SURFACE_VOLUME)
839 return false;
840
841 return pSurface->surfaceFlags & SVGA3D_SURFACE_SCREENTARGET
842 || pSurface->surfaceFlags & SVGA3D_SURFACE_BIND_RENDER_TARGET;
843}
844
845
846DXDEVICE *dxDeviceFromCid(uint32_t cid, PVMSVGA3DSTATE pState)
847{
848 if (cid != DX_CID_BACKEND)
849 {
850 VMSVGA3DDXCONTEXT *pDXContext;
851 int rc = vmsvga3dDXContextFromCid(pState, cid, &pDXContext);
852 if (RT_SUCCESS(rc))
853 return &pDXContext->pBackendDXContext->device;
854 }
855 else
856 return &pState->pBackend->device;
857
858 AssertFailed();
859 return NULL;
860}
861
862
863static int dxDeviceFlush(DXDEVICE *pDevice)
864{
865 /** @todo Should the flush follow the query submission? */
866 pDevice->pImmediateContext->Flush();
867
868 ID3D11Query *pQuery = 0;
869 D3D11_QUERY_DESC qd;
870 RT_ZERO(qd);
871 qd.Query = D3D11_QUERY_EVENT;
872
873 HRESULT hr = pDevice->pDevice->CreateQuery(&qd, &pQuery);
874 Assert(hr == S_OK); RT_NOREF(hr);
875 pDevice->pImmediateContext->End(pQuery);
876
877 BOOL queryData;
878 while (pDevice->pImmediateContext->GetData(pQuery, &queryData, sizeof(queryData), 0) != S_OK)
879 RTThreadYield();
880
881 D3D_RELEASE(pQuery);
882
883 return VINF_SUCCESS;
884}
885
886
887static int dxContextWait(uint32_t cidDrawing, PVMSVGA3DSTATE pState)
888{
889 /* Flush cidDrawing context and issue a query. */
890 DXDEVICE *pDXDevice = dxDeviceFromCid(cidDrawing, pState);
891 if (pDXDevice)
892 return dxDeviceFlush(pDXDevice);
893 /* cidDrawing does not exist anymore. */
894 return VINF_SUCCESS;
895}
896
897
898static int dxSurfaceWait(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface, uint32_t cidRequesting)
899{
900 VMSVGA3DBACKENDSURFACE *pBackendSurface = pSurface->pBackendSurface;
901 if (!pBackendSurface)
902 AssertFailedReturn(VERR_INVALID_STATE);
903
904 int rc = VINF_SUCCESS;
905 if (pBackendSurface->cidDrawing != SVGA_ID_INVALID)
906 {
907 if (pBackendSurface->cidDrawing != cidRequesting)
908 {
909 LogFunc(("sid = %u, assoc cid = %u, drawing cid = %u, req cid = %u\n",
910 pSurface->id, pSurface->idAssociatedContext, pBackendSurface->cidDrawing, cidRequesting));
911 Assert(dxIsSurfaceShareable(pSurface));
912 rc = dxContextWait(pBackendSurface->cidDrawing, pState);
913 pBackendSurface->cidDrawing = SVGA_ID_INVALID;
914 }
915 }
916 return rc;
917}
918
919
920static ID3D11Resource *dxResource(PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface, VMSVGA3DDXCONTEXT *pDXContext)
921{
922 VMSVGA3DBACKENDSURFACE *pBackendSurface = pSurface->pBackendSurface;
923 if (!pBackendSurface)
924 AssertFailedReturn(NULL);
925
926 ID3D11Resource *pResource;
927
928 uint32_t const cidRequesting = pDXContext ? pDXContext->cid : DX_CID_BACKEND;
929 if (cidRequesting == pSurface->idAssociatedContext)
930 pResource = pBackendSurface->u.pResource;
931 else
932 {
933 /*
934 * Context, which as not created the surface, is requesting.
935 */
936 AssertReturn(pDXContext, NULL);
937
938 Assert(dxIsSurfaceShareable(pSurface));
939 Assert(pSurface->idAssociatedContext == DX_CID_BACKEND);
940
941 DXSHAREDTEXTURE *pSharedTexture = (DXSHAREDTEXTURE *)RTAvlU32Get(&pBackendSurface->SharedTextureTree, pDXContext->cid);
942 if (!pSharedTexture)
943 {
944 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
945 AssertReturn(pDevice->pDevice, NULL);
946
947 AssertReturn(pBackendSurface->SharedHandle, NULL);
948
949 /* This context has not yet opened the texture. */
950 pSharedTexture = (DXSHAREDTEXTURE *)RTMemAllocZ(sizeof(DXSHAREDTEXTURE));
951 AssertReturn(pSharedTexture, NULL);
952
953 pSharedTexture->Core.Key = pDXContext->cid;
954 bool const fSuccess = RTAvlU32Insert(&pBackendSurface->SharedTextureTree, &pSharedTexture->Core);
955 AssertReturn(fSuccess, NULL);
956
957 HRESULT hr = pDevice->pDevice->OpenSharedResource(pBackendSurface->SharedHandle, __uuidof(ID3D11Texture2D), (void**)&pSharedTexture->pTexture);
958 Assert(SUCCEEDED(hr));
959 if (SUCCEEDED(hr))
960 pSharedTexture->sid = pSurface->id;
961 else
962 {
963 RTAvlU32Remove(&pBackendSurface->SharedTextureTree, pDXContext->cid);
964 RTMemFree(pSharedTexture);
965 return NULL;
966 }
967 }
968
969 pResource = pSharedTexture->pTexture;
970 }
971
972 /* Wait for drawing to finish. */
973 dxSurfaceWait(pState, pSurface, cidRequesting);
974
975 return pResource;
976}
977
978
979static uint32_t dxGetRenderTargetViewSid(PVMSVGA3DDXCONTEXT pDXContext, uint32_t renderTargetViewId)
980{
981 ASSERT_GUEST_RETURN(renderTargetViewId < pDXContext->cot.cRTView, SVGA_ID_INVALID);
982
983 SVGACOTableDXRTViewEntry const *pRTViewEntry = &pDXContext->cot.paRTView[renderTargetViewId];
984 return pRTViewEntry->sid;
985}
986
987
988static uint32_t dxGetShaderResourceViewSid(PVMSVGA3DDXCONTEXT pDXContext, uint32_t shaderResourceViewId)
989{
990 ASSERT_GUEST_RETURN(shaderResourceViewId < pDXContext->cot.cSRView, SVGA_ID_INVALID);
991
992 SVGACOTableDXSRViewEntry const *pSRViewEntry = &pDXContext->cot.paSRView[shaderResourceViewId];
993 return pSRViewEntry->sid;
994}
995
996
997static int dxTrackRenderTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
998{
999 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
1000 AssertReturn(pState, VERR_INVALID_STATE);
1001
1002 for (int i = 0; i < RT_ELEMENTS(pDXContext->svgaDXContext.renderState.renderTargetViewIds); ++i)
1003 {
1004 uint32_t const renderTargetViewId = pDXContext->svgaDXContext.renderState.renderTargetViewIds[i];
1005 if (renderTargetViewId == SVGA_ID_INVALID)
1006 continue;
1007
1008 uint32_t const sid = dxGetRenderTargetViewSid(pDXContext, renderTargetViewId);
1009 LogFunc(("[%u] sid = %u, drawing cid = %u\n", i, sid, pDXContext->cid));
1010
1011 PVMSVGA3DSURFACE pSurface;
1012 int rc = vmsvga3dSurfaceFromSid(pState, sid, &pSurface);
1013 if (RT_SUCCESS(rc))
1014 {
1015 AssertContinue(pSurface->pBackendSurface);
1016 pSurface->pBackendSurface->cidDrawing = pDXContext->cid;
1017 }
1018 }
1019 return VINF_SUCCESS;
1020}
1021
1022
1023static int dxDefineStreamOutput(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid, SVGACOTableDXStreamOutputEntry const *pEntry)
1024{
1025 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
1026
1027 /* Make D3D11_SO_DECLARATION_ENTRY array from SVGA3dStreamOutputDeclarationEntry. */
1028 pDXStreamOutput->cDeclarationEntry = pEntry->numOutputStreamEntries;
1029 for (uint32_t i = 0; i < pDXStreamOutput->cDeclarationEntry; ++i)
1030 {
1031 D3D11_SO_DECLARATION_ENTRY *pDst = &pDXStreamOutput->aDeclarationEntry[i];
1032 SVGA3dStreamOutputDeclarationEntry const *pSrc = &pEntry->decl[i];
1033
1034 uint32_t const registerMask = pSrc->registerMask & 0xF;
1035 unsigned const iFirstBit = ASMBitFirstSetU32(registerMask);
1036 unsigned const iLastBit = ASMBitLastSetU32(registerMask);
1037
1038 pDst->Stream = pSrc->stream;
1039 pDst->SemanticName = NULL; /* Will be taken from the shader output declaration. */
1040 pDst->SemanticIndex = 0;
1041 pDst->StartComponent = iFirstBit > 0 ? iFirstBit - 1 : 0;
1042 pDst->ComponentCount = iFirstBit > 0 ? iLastBit - (iFirstBit - 1) : 0;
1043 pDst->OutputSlot = pSrc->outputSlot;
1044 }
1045
1046 return VINF_SUCCESS;
1047}
1048
1049static void dxDestroyStreamOutput(DXSTREAMOUTPUT *pDXStreamOutput)
1050{
1051 RT_NOREF(pDXStreamOutput);
1052}
1053
1054static D3D11_BLEND dxBlendFactorAlpha(uint8_t svgaBlend)
1055{
1056 /* "Blend options that end in _COLOR are not allowed." but the guest sometimes sends them. */
1057 switch (svgaBlend)
1058 {
1059 case SVGA3D_BLENDOP_SRCCOLOR: return D3D11_BLEND_SRC_ALPHA;
1060 case SVGA3D_BLENDOP_INVSRCCOLOR: return D3D11_BLEND_INV_SRC_ALPHA;
1061 case SVGA3D_BLENDOP_DESTCOLOR: return D3D11_BLEND_DEST_ALPHA;
1062 case SVGA3D_BLENDOP_INVDESTCOLOR: return D3D11_BLEND_INV_DEST_ALPHA;
1063 case SVGA3D_BLENDOP_SRC1COLOR: return D3D11_BLEND_SRC1_ALPHA;
1064 case SVGA3D_BLENDOP_INVSRC1COLOR: return D3D11_BLEND_INV_SRC1_ALPHA;
1065 default:
1066 break;
1067 }
1068 return (D3D11_BLEND)svgaBlend;
1069}
1070
1071
1072static D3D11_BLEND dxBlendFactorColor(uint8_t svgaBlend)
1073{
1074 return (D3D11_BLEND)svgaBlend;
1075}
1076
1077
1078static D3D11_BLEND_OP dxBlendOp(uint8_t svgaBlendEq)
1079{
1080 return (D3D11_BLEND_OP)svgaBlendEq;
1081}
1082
1083
1084/** @todo AssertCompile for types like D3D11_COMPARISON_FUNC and SVGA3dComparisonFunc */
1085static HRESULT dxBlendStateCreate(DXDEVICE *pDevice, SVGACOTableDXBlendStateEntry const *pEntry, ID3D11BlendState **pp)
1086{
1087 D3D11_BLEND_DESC BlendDesc;
1088 BlendDesc.AlphaToCoverageEnable = RT_BOOL(pEntry->alphaToCoverageEnable);
1089 BlendDesc.IndependentBlendEnable = RT_BOOL(pEntry->independentBlendEnable);
1090 for (int i = 0; i < SVGA3D_MAX_RENDER_TARGETS; ++i)
1091 {
1092 BlendDesc.RenderTarget[i].BlendEnable = RT_BOOL(pEntry->perRT[i].blendEnable);
1093 BlendDesc.RenderTarget[i].SrcBlend = dxBlendFactorColor(pEntry->perRT[i].srcBlend);
1094 BlendDesc.RenderTarget[i].DestBlend = dxBlendFactorColor(pEntry->perRT[i].destBlend);
1095 BlendDesc.RenderTarget[i].BlendOp = dxBlendOp (pEntry->perRT[i].blendOp);
1096 BlendDesc.RenderTarget[i].SrcBlendAlpha = dxBlendFactorAlpha(pEntry->perRT[i].srcBlendAlpha);
1097 BlendDesc.RenderTarget[i].DestBlendAlpha = dxBlendFactorAlpha(pEntry->perRT[i].destBlendAlpha);
1098 BlendDesc.RenderTarget[i].BlendOpAlpha = dxBlendOp (pEntry->perRT[i].blendOpAlpha);
1099 BlendDesc.RenderTarget[i].RenderTargetWriteMask = pEntry->perRT[i].renderTargetWriteMask;
1100 /** @todo logicOpEnable and logicOp */
1101 }
1102
1103 HRESULT hr = pDevice->pDevice->CreateBlendState(&BlendDesc, pp);
1104 Assert(SUCCEEDED(hr));
1105 return hr;
1106}
1107
1108
1109static HRESULT dxDepthStencilStateCreate(DXDEVICE *pDevice, SVGACOTableDXDepthStencilEntry const *pEntry, ID3D11DepthStencilState **pp)
1110{
1111 D3D11_DEPTH_STENCIL_DESC desc;
1112 desc.DepthEnable = pEntry->depthEnable;
1113 desc.DepthWriteMask = (D3D11_DEPTH_WRITE_MASK)pEntry->depthWriteMask;
1114 desc.DepthFunc = (D3D11_COMPARISON_FUNC)pEntry->depthFunc;
1115 desc.StencilEnable = pEntry->stencilEnable;
1116 desc.StencilReadMask = pEntry->stencilReadMask;
1117 desc.StencilWriteMask = pEntry->stencilWriteMask;
1118 desc.FrontFace.StencilFailOp = (D3D11_STENCIL_OP)pEntry->frontStencilFailOp;
1119 desc.FrontFace.StencilDepthFailOp = (D3D11_STENCIL_OP)pEntry->frontStencilDepthFailOp;
1120 desc.FrontFace.StencilPassOp = (D3D11_STENCIL_OP)pEntry->frontStencilPassOp;
1121 desc.FrontFace.StencilFunc = (D3D11_COMPARISON_FUNC)pEntry->frontStencilFunc;
1122 desc.BackFace.StencilFailOp = (D3D11_STENCIL_OP)pEntry->backStencilFailOp;
1123 desc.BackFace.StencilDepthFailOp = (D3D11_STENCIL_OP)pEntry->backStencilDepthFailOp;
1124 desc.BackFace.StencilPassOp = (D3D11_STENCIL_OP)pEntry->backStencilPassOp;
1125 desc.BackFace.StencilFunc = (D3D11_COMPARISON_FUNC)pEntry->backStencilFunc;
1126 /** @todo frontEnable, backEnable */
1127
1128 HRESULT hr = pDevice->pDevice->CreateDepthStencilState(&desc, pp);
1129 Assert(SUCCEEDED(hr));
1130 return hr;
1131}
1132
1133
1134static HRESULT dxSamplerStateCreate(DXDEVICE *pDevice, SVGACOTableDXSamplerEntry const *pEntry, ID3D11SamplerState **pp)
1135{
1136 D3D11_SAMPLER_DESC desc;
1137 /* Guest sometimes sends inconsistent (from D3D11 point of view) set of filter flags. */
1138 if (pEntry->filter & SVGA3D_FILTER_ANISOTROPIC)
1139 desc.Filter = (pEntry->filter & SVGA3D_FILTER_COMPARE)
1140 ? D3D11_FILTER_COMPARISON_ANISOTROPIC
1141 : D3D11_FILTER_ANISOTROPIC;
1142 else
1143 desc.Filter = (D3D11_FILTER)pEntry->filter;
1144 desc.AddressU = (D3D11_TEXTURE_ADDRESS_MODE)pEntry->addressU;
1145 desc.AddressV = (D3D11_TEXTURE_ADDRESS_MODE)pEntry->addressV;
1146 desc.AddressW = (D3D11_TEXTURE_ADDRESS_MODE)pEntry->addressW;
1147 desc.MipLODBias = pEntry->mipLODBias;
1148 desc.MaxAnisotropy = RT_CLAMP(pEntry->maxAnisotropy, 1, 16); /* "Valid values are between 1 and 16" */
1149 desc.ComparisonFunc = (D3D11_COMPARISON_FUNC)pEntry->comparisonFunc;
1150 desc.BorderColor[0] = pEntry->borderColor.value[0];
1151 desc.BorderColor[1] = pEntry->borderColor.value[1];
1152 desc.BorderColor[2] = pEntry->borderColor.value[2];
1153 desc.BorderColor[3] = pEntry->borderColor.value[3];
1154 desc.MinLOD = pEntry->minLOD;
1155 desc.MaxLOD = pEntry->maxLOD;
1156
1157 HRESULT hr = pDevice->pDevice->CreateSamplerState(&desc, pp);
1158 Assert(SUCCEEDED(hr));
1159 return hr;
1160}
1161
1162
1163static HRESULT dxRasterizerStateCreate(DXDEVICE *pDevice, SVGACOTableDXRasterizerStateEntry const *pEntry, ID3D11RasterizerState **pp)
1164{
1165 D3D11_RASTERIZER_DESC desc;
1166 desc.FillMode = (D3D11_FILL_MODE)pEntry->fillMode;
1167 desc.CullMode = (D3D11_CULL_MODE)pEntry->cullMode;
1168 desc.FrontCounterClockwise = pEntry->frontCounterClockwise;
1169 /** @todo provokingVertexLast */
1170 desc.DepthBias = pEntry->depthBias;
1171 desc.DepthBiasClamp = pEntry->depthBiasClamp;
1172 desc.SlopeScaledDepthBias = pEntry->slopeScaledDepthBias;
1173 desc.DepthClipEnable = pEntry->depthClipEnable;
1174 desc.ScissorEnable = pEntry->scissorEnable;
1175 desc.MultisampleEnable = pEntry->multisampleEnable;
1176 desc.AntialiasedLineEnable = pEntry->antialiasedLineEnable;
1177 /** @todo lineWidth lineStippleEnable lineStippleFactor lineStipplePattern forcedSampleCount */
1178
1179 HRESULT hr = pDevice->pDevice->CreateRasterizerState(&desc, pp);
1180 Assert(SUCCEEDED(hr));
1181 return hr;
1182}
1183
1184
1185static HRESULT dxRenderTargetViewCreate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableDXRTViewEntry const *pEntry, VMSVGA3DSURFACE *pSurface, ID3D11RenderTargetView **pp)
1186{
1187 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
1188
1189 ID3D11Resource *pResource = dxResource(pThisCC->svga.p3dState, pSurface, pDXContext);
1190
1191 D3D11_RENDER_TARGET_VIEW_DESC desc;
1192 RT_ZERO(desc);
1193 desc.Format = vmsvgaDXSurfaceFormat2Dxgi(pEntry->format);
1194 AssertReturn(desc.Format != DXGI_FORMAT_UNKNOWN, E_FAIL);
1195 switch (pEntry->resourceDimension)
1196 {
1197 case SVGA3D_RESOURCE_BUFFER:
1198 desc.ViewDimension = D3D11_RTV_DIMENSION_BUFFER;
1199 desc.Buffer.FirstElement = pEntry->desc.buffer.firstElement;
1200 desc.Buffer.NumElements = pEntry->desc.buffer.numElements;
1201 break;
1202 case SVGA3D_RESOURCE_TEXTURE1D:
1203 if (pEntry->desc.tex.arraySize <= 1)
1204 {
1205 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D;
1206 desc.Texture1D.MipSlice = pEntry->desc.tex.mipSlice;
1207 }
1208 else
1209 {
1210 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1DARRAY;
1211 desc.Texture1DArray.MipSlice = pEntry->desc.tex.mipSlice;
1212 desc.Texture1DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
1213 desc.Texture1DArray.ArraySize = pEntry->desc.tex.arraySize;
1214 }
1215 break;
1216 case SVGA3D_RESOURCE_TEXTURE2D:
1217 if (pEntry->desc.tex.arraySize <= 1)
1218 {
1219 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
1220 desc.Texture2D.MipSlice = pEntry->desc.tex.mipSlice;
1221 }
1222 else
1223 {
1224 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1225 desc.Texture2DArray.MipSlice = pEntry->desc.tex.mipSlice;
1226 desc.Texture2DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
1227 desc.Texture2DArray.ArraySize = pEntry->desc.tex.arraySize;
1228 }
1229 break;
1230 case SVGA3D_RESOURCE_TEXTURE3D:
1231 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
1232 desc.Texture3D.MipSlice = pEntry->desc.tex3D.mipSlice;
1233 desc.Texture3D.FirstWSlice = pEntry->desc.tex3D.firstW;
1234 desc.Texture3D.WSize = pEntry->desc.tex3D.wSize;
1235 break;
1236 case SVGA3D_RESOURCE_TEXTURECUBE:
1237 AssertFailed(); /** @todo test. Probably not applicable to a render target view. */
1238 desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
1239 desc.Texture2DArray.MipSlice = pEntry->desc.tex.mipSlice;
1240 desc.Texture2DArray.FirstArraySlice = 0;
1241 desc.Texture2DArray.ArraySize = 6;
1242 break;
1243 case SVGA3D_RESOURCE_BUFFEREX:
1244 AssertFailed(); /** @todo test. Probably not applicable to a render target view. */
1245 desc.ViewDimension = D3D11_RTV_DIMENSION_BUFFER;
1246 desc.Buffer.FirstElement = pEntry->desc.buffer.firstElement;
1247 desc.Buffer.NumElements = pEntry->desc.buffer.numElements;
1248 break;
1249 default:
1250 ASSERT_GUEST_FAILED_RETURN(E_INVALIDARG);
1251 }
1252
1253 HRESULT hr = pDevice->pDevice->CreateRenderTargetView(pResource, &desc, pp);
1254 Assert(SUCCEEDED(hr));
1255 return hr;
1256}
1257
1258
1259static HRESULT dxShaderResourceViewCreate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableDXSRViewEntry const *pEntry, VMSVGA3DSURFACE *pSurface, ID3D11ShaderResourceView **pp)
1260{
1261 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
1262
1263 ID3D11Resource *pResource = dxResource(pThisCC->svga.p3dState, pSurface, pDXContext);
1264
1265 D3D11_SHADER_RESOURCE_VIEW_DESC desc;
1266 RT_ZERO(desc);
1267 desc.Format = vmsvgaDXSurfaceFormat2Dxgi(pEntry->format);
1268 AssertReturn(desc.Format != DXGI_FORMAT_UNKNOWN, E_FAIL);
1269
1270 switch (pEntry->resourceDimension)
1271 {
1272 case SVGA3D_RESOURCE_BUFFER:
1273 desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
1274 desc.Buffer.FirstElement = pEntry->desc.buffer.firstElement;
1275 desc.Buffer.NumElements = pEntry->desc.buffer.numElements;
1276 break;
1277 case SVGA3D_RESOURCE_TEXTURE1D:
1278 if (pEntry->desc.tex.arraySize <= 1)
1279 {
1280 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
1281 desc.Texture1D.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
1282 desc.Texture1D.MipLevels = pEntry->desc.tex.mipLevels;
1283 }
1284 else
1285 {
1286 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY;
1287 desc.Texture1DArray.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
1288 desc.Texture1DArray.MipLevels = pEntry->desc.tex.mipLevels;
1289 desc.Texture1DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
1290 desc.Texture1DArray.ArraySize = pEntry->desc.tex.arraySize;
1291 }
1292 break;
1293 case SVGA3D_RESOURCE_TEXTURE2D:
1294 if (pEntry->desc.tex.arraySize <= 1)
1295 {
1296 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
1297 desc.Texture2D.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
1298 desc.Texture2D.MipLevels = pEntry->desc.tex.mipLevels;
1299 }
1300 else
1301 {
1302 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
1303 desc.Texture2DArray.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
1304 desc.Texture2DArray.MipLevels = pEntry->desc.tex.mipLevels;
1305 desc.Texture2DArray.FirstArraySlice = pEntry->desc.tex.firstArraySlice;
1306 desc.Texture2DArray.ArraySize = pEntry->desc.tex.arraySize;
1307 }
1308 break;
1309 case SVGA3D_RESOURCE_TEXTURE3D:
1310 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
1311 desc.Texture3D.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
1312 desc.Texture3D.MipLevels = pEntry->desc.tex.mipLevels;
1313 break;
1314 case SVGA3D_RESOURCE_TEXTURECUBE:
1315 desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
1316 desc.TextureCube.MostDetailedMip = pEntry->desc.tex.mostDetailedMip;
1317 desc.TextureCube.MipLevels = pEntry->desc.tex.mipLevels;
1318 break;
1319 case SVGA3D_RESOURCE_BUFFEREX:
1320 AssertFailed(); /** @todo test. */
1321 desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFEREX;
1322 desc.BufferEx.FirstElement = pEntry->desc.bufferex.firstElement;
1323 desc.BufferEx.NumElements = pEntry->desc.bufferex.numElements;
1324 desc.BufferEx.Flags = pEntry->desc.bufferex.flags;
1325 break;
1326 default:
1327 ASSERT_GUEST_FAILED_RETURN(E_INVALIDARG);
1328 }
1329
1330 HRESULT hr = pDevice->pDevice->CreateShaderResourceView(pResource, &desc, pp);
1331 Assert(SUCCEEDED(hr));
1332 return hr;
1333}
1334
1335
1336static HRESULT dxDepthStencilViewCreate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableDXDSViewEntry const *pEntry, VMSVGA3DSURFACE *pSurface, ID3D11DepthStencilView **pp)
1337{
1338 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
1339
1340 ID3D11Resource *pResource = dxResource(pThisCC->svga.p3dState, pSurface, pDXContext);
1341
1342 D3D11_DEPTH_STENCIL_VIEW_DESC desc;
1343 RT_ZERO(desc);
1344 desc.Format = vmsvgaDXSurfaceFormat2Dxgi(pEntry->format);
1345 AssertReturn(desc.Format != DXGI_FORMAT_UNKNOWN, E_FAIL);
1346 desc.Flags = pEntry->flags;
1347 switch (pEntry->resourceDimension)
1348 {
1349 case SVGA3D_RESOURCE_TEXTURE1D:
1350 if (pEntry->arraySize <= 1)
1351 {
1352 desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1D;
1353 desc.Texture1D.MipSlice = pEntry->mipSlice;
1354 }
1355 else
1356 {
1357 desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE1DARRAY;
1358 desc.Texture1DArray.MipSlice = pEntry->mipSlice;
1359 desc.Texture1DArray.FirstArraySlice = pEntry->firstArraySlice;
1360 desc.Texture1DArray.ArraySize = pEntry->arraySize;
1361 }
1362 break;
1363 case SVGA3D_RESOURCE_TEXTURE2D:
1364 if (pEntry->arraySize <= 1)
1365 {
1366 desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
1367 desc.Texture2D.MipSlice = pEntry->mipSlice;
1368 }
1369 else
1370 {
1371 desc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
1372 desc.Texture2DArray.MipSlice = pEntry->mipSlice;
1373 desc.Texture2DArray.FirstArraySlice = pEntry->firstArraySlice;
1374 desc.Texture2DArray.ArraySize = pEntry->arraySize;
1375 }
1376 break;
1377 default:
1378 ASSERT_GUEST_FAILED_RETURN(E_INVALIDARG);
1379 }
1380
1381 HRESULT hr = pDevice->pDevice->CreateDepthStencilView(pResource, &desc, pp);
1382 Assert(SUCCEEDED(hr));
1383 return hr;
1384}
1385
1386
1387static HRESULT dxShaderCreate(PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSHADER pShader, DXSHADER *pDXShader)
1388{
1389 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
1390
1391 HRESULT hr = S_OK;
1392
1393 switch (pShader->type)
1394 {
1395 case SVGA3D_SHADERTYPE_VS:
1396 hr = pDevice->pDevice->CreateVertexShader(pDXShader->pvDXBC, pDXShader->cbDXBC, NULL, &pDXShader->pVertexShader);
1397 Assert(SUCCEEDED(hr));
1398 break;
1399 case SVGA3D_SHADERTYPE_PS:
1400 hr = pDevice->pDevice->CreatePixelShader(pDXShader->pvDXBC, pDXShader->cbDXBC, NULL, &pDXShader->pPixelShader);
1401 Assert(SUCCEEDED(hr));
1402 break;
1403 case SVGA3D_SHADERTYPE_GS:
1404 {
1405 SVGA3dStreamOutputId const soid = pDXContext->svgaDXContext.streamOut.soid;
1406 if (soid == SVGA_ID_INVALID)
1407 hr = pDevice->pDevice->CreateGeometryShader(pDXShader->pvDXBC, pDXShader->cbDXBC, NULL, &pDXShader->pGeometryShader);
1408 else
1409 {
1410 ASSERT_GUEST_RETURN(soid < pDXContext->pBackendDXContext->cStreamOutput, E_INVALIDARG);
1411
1412 SVGACOTableDXStreamOutputEntry const *pEntry = &pDXContext->cot.paStreamOutput[soid];
1413 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
1414 uint32_t const cSOTarget = pDXContext->pBackendDXContext->cSOTarget;
1415
1416 for (uint32_t i = 0; i < pDXStreamOutput->cDeclarationEntry; ++i)
1417 {
1418 D3D11_SO_DECLARATION_ENTRY *p = &pDXStreamOutput->aDeclarationEntry[i];
1419 SVGA3dStreamOutputDeclarationEntry const *decl = &pEntry->decl[i];
1420 p->SemanticName = DXShaderGetOutputSemanticName(&pShader->shaderInfo, decl->registerIndex);
1421 }
1422
1423 hr = pDevice->pDevice->CreateGeometryShaderWithStreamOutput(pDXShader->pvDXBC, pDXShader->cbDXBC,
1424 pDXStreamOutput->aDeclarationEntry, pDXStreamOutput->cDeclarationEntry,
1425 pEntry->streamOutputStrideInBytes, cSOTarget, pEntry->rasterizedStream,
1426 /*pClassLinkage=*/ NULL, &pDXShader->pGeometryShader);
1427 if (SUCCEEDED(hr))
1428 pDXShader->soid = soid;
1429 }
1430 Assert(SUCCEEDED(hr));
1431 break;
1432 }
1433 case SVGA3D_SHADERTYPE_HS:
1434 case SVGA3D_SHADERTYPE_DS:
1435 case SVGA3D_SHADERTYPE_CS:
1436 default:
1437 ASSERT_GUEST_FAILED_RETURN(E_INVALIDARG);
1438 }
1439
1440 return hr;
1441}
1442
1443
1444static void dxShaderSet(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderType type, DXSHADER *pDXShader)
1445{
1446 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
1447
1448 switch (type)
1449 {
1450 case SVGA3D_SHADERTYPE_VS:
1451 pDevice->pImmediateContext->VSSetShader(pDXShader ? pDXShader->pVertexShader : NULL, NULL, 0);
1452 break;
1453 case SVGA3D_SHADERTYPE_PS:
1454 pDevice->pImmediateContext->PSSetShader(pDXShader ? pDXShader->pPixelShader : NULL, NULL, 0);
1455 break;
1456 case SVGA3D_SHADERTYPE_GS:
1457 {
1458 Assert(!pDXShader || (pDXShader->soid == pDXContext->svgaDXContext.streamOut.soid));
1459 pDevice->pImmediateContext->GSSetShader(pDXShader ? pDXShader->pGeometryShader : NULL, NULL, 0);
1460 } break;
1461 case SVGA3D_SHADERTYPE_HS:
1462 case SVGA3D_SHADERTYPE_DS:
1463 case SVGA3D_SHADERTYPE_CS:
1464 default:
1465 ASSERT_GUEST_FAILED_RETURN_VOID();
1466 }
1467}
1468
1469
1470static void dxConstantBufferSet(DXDEVICE *pDevice, uint32_t slot, SVGA3dShaderType type, ID3D11Buffer *pConstantBuffer)
1471{
1472 switch (type)
1473 {
1474 case SVGA3D_SHADERTYPE_VS:
1475 pDevice->pImmediateContext->VSSetConstantBuffers(slot, 1, &pConstantBuffer);
1476 break;
1477 case SVGA3D_SHADERTYPE_PS:
1478 pDevice->pImmediateContext->PSSetConstantBuffers(slot, 1, &pConstantBuffer);
1479 break;
1480 case SVGA3D_SHADERTYPE_GS:
1481 pDevice->pImmediateContext->GSSetConstantBuffers(slot, 1, &pConstantBuffer);
1482 break;
1483 case SVGA3D_SHADERTYPE_HS:
1484 case SVGA3D_SHADERTYPE_DS:
1485 case SVGA3D_SHADERTYPE_CS:
1486 default:
1487 ASSERT_GUEST_FAILED_RETURN_VOID();
1488 }
1489}
1490
1491
1492static void dxSamplerSet(DXDEVICE *pDevice, SVGA3dShaderType type, uint32_t startSampler, uint32_t cSampler, ID3D11SamplerState * const *papSampler)
1493{
1494 switch (type)
1495 {
1496 case SVGA3D_SHADERTYPE_VS:
1497 pDevice->pImmediateContext->VSSetSamplers(startSampler, cSampler, papSampler);
1498 break;
1499 case SVGA3D_SHADERTYPE_PS:
1500 pDevice->pImmediateContext->PSSetSamplers(startSampler, cSampler, papSampler);
1501 break;
1502 case SVGA3D_SHADERTYPE_GS:
1503 pDevice->pImmediateContext->GSSetSamplers(startSampler, cSampler, papSampler);
1504 break;
1505 case SVGA3D_SHADERTYPE_HS:
1506 case SVGA3D_SHADERTYPE_DS:
1507 case SVGA3D_SHADERTYPE_CS:
1508 default:
1509 ASSERT_GUEST_FAILED_RETURN_VOID();
1510 }
1511}
1512
1513
1514static void dxShaderResourceViewSet(DXDEVICE *pDevice, SVGA3dShaderType type, uint32_t startView, uint32_t cShaderResourceView, ID3D11ShaderResourceView * const *papShaderResourceView)
1515{
1516 switch (type)
1517 {
1518 case SVGA3D_SHADERTYPE_VS:
1519 pDevice->pImmediateContext->VSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
1520 break;
1521 case SVGA3D_SHADERTYPE_PS:
1522 pDevice->pImmediateContext->PSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
1523 break;
1524 case SVGA3D_SHADERTYPE_GS:
1525 pDevice->pImmediateContext->GSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
1526 break;
1527 case SVGA3D_SHADERTYPE_HS:
1528 case SVGA3D_SHADERTYPE_DS:
1529 case SVGA3D_SHADERTYPE_CS:
1530 default:
1531 ASSERT_GUEST_FAILED_RETURN_VOID();
1532 }
1533}
1534
1535
1536static int dxBackendSurfaceAlloc(PVMSVGA3DBACKENDSURFACE *ppBackendSurface)
1537{
1538 PVMSVGA3DBACKENDSURFACE pBackendSurface = (PVMSVGA3DBACKENDSURFACE)RTMemAllocZ(sizeof(VMSVGA3DBACKENDSURFACE));
1539 AssertPtrReturn(pBackendSurface, VERR_NO_MEMORY);
1540 pBackendSurface->cidDrawing = SVGA_ID_INVALID;
1541 *ppBackendSurface = pBackendSurface;
1542 return VINF_SUCCESS;
1543}
1544
1545
1546static int vmsvga3dBackSurfaceCreateScreenTarget(PVGASTATECC pThisCC, PVMSVGA3DSURFACE pSurface)
1547{
1548 PVMSVGA3DSTATE p3dState = pThisCC->svga.p3dState;
1549 AssertReturn(p3dState, VERR_INVALID_STATE);
1550
1551 PVMSVGA3DBACKEND pBackend = p3dState->pBackend;
1552 AssertReturn(pBackend, VERR_INVALID_STATE);
1553
1554 DXDEVICE *pDXDevice = &pBackend->device;
1555 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
1556
1557 /* Surface must have SCREEN_TARGET flag. */
1558 ASSERT_GUEST_RETURN(RT_BOOL(pSurface->surfaceFlags & SVGA3D_SURFACE_SCREENTARGET), VERR_INVALID_PARAMETER);
1559
1560 if (VMSVGA3DSURFACE_HAS_HW_SURFACE(pSurface))
1561 {
1562 AssertFailed(); /* Should the function not be used like that? */
1563 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
1564 }
1565
1566 PVMSVGA3DBACKENDSURFACE pBackendSurface;
1567 int rc = dxBackendSurfaceAlloc(&pBackendSurface);
1568 AssertRCReturn(rc, rc);
1569
1570 D3D11_TEXTURE2D_DESC td;
1571 RT_ZERO(td);
1572 td.Width = pSurface->paMipmapLevels[0].mipmapSize.width;
1573 td.Height = pSurface->paMipmapLevels[0].mipmapSize.height;
1574 Assert(pSurface->cLevels == 1);
1575 td.MipLevels = 1;
1576 td.ArraySize = 1;
1577 td.Format = vmsvgaDXSurfaceFormat2Dxgi(pSurface->format);
1578 td.SampleDesc.Count = 1;
1579 td.SampleDesc.Quality = 0;
1580 td.Usage = D3D11_USAGE_DEFAULT;
1581 td.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
1582 td.CPUAccessFlags = 0;
1583 td.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
1584
1585 HRESULT hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->u.pTexture2D);
1586 Assert(SUCCEEDED(hr));
1587 if (SUCCEEDED(hr))
1588 {
1589 /* Map-able texture. */
1590 td.Usage = D3D11_USAGE_DYNAMIC;
1591 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
1592 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1593 td.MiscFlags = 0;
1594 hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->pDynamicTexture);
1595 Assert(SUCCEEDED(hr));
1596 }
1597
1598 if (SUCCEEDED(hr))
1599 {
1600 /* Staging texture. */
1601 td.Usage = D3D11_USAGE_STAGING;
1602 td.BindFlags = 0; /* No flags allowed. */
1603 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
1604 hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->pStagingTexture);
1605 Assert(SUCCEEDED(hr));
1606 }
1607
1608 if (SUCCEEDED(hr))
1609 {
1610 /* Get the shared handle. */
1611 IDXGIResource *pDxgiResource = NULL;
1612 hr = pBackendSurface->u.pTexture2D->QueryInterface(__uuidof(IDXGIResource), (void**)&pDxgiResource);
1613 Assert(SUCCEEDED(hr));
1614 if (SUCCEEDED(hr))
1615 {
1616 hr = pDxgiResource->GetSharedHandle(&pBackendSurface->SharedHandle);
1617 Assert(SUCCEEDED(hr));
1618 D3D_RELEASE(pDxgiResource);
1619 }
1620 }
1621
1622 if (SUCCEEDED(hr))
1623 {
1624 /*
1625 * Success.
1626 */
1627 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_SCREEN_TARGET;
1628 pBackendSurface->enmDxgiFormat = td.Format;
1629 pSurface->pBackendSurface = pBackendSurface;
1630 pSurface->idAssociatedContext = DX_CID_BACKEND;
1631 pSurface->fDirty = true;
1632 return VINF_SUCCESS;
1633 }
1634
1635 /* Failure. */
1636 D3D_RELEASE(pBackendSurface->pStagingTexture);
1637 D3D_RELEASE(pBackendSurface->pDynamicTexture);
1638 D3D_RELEASE(pBackendSurface->u.pTexture2D);
1639 RTMemFree(pBackendSurface);
1640 return VERR_NO_MEMORY;
1641}
1642
1643
1644static UINT dxBindFlags(SVGA3dSurfaceAllFlags surfaceFlags)
1645{
1646 /* Catch unimplemented flags. */
1647 Assert(!RT_BOOL(surfaceFlags & (SVGA3D_SURFACE_BIND_LOGICOPS | SVGA3D_SURFACE_BIND_RAW_VIEWS)));
1648
1649 UINT BindFlags = 0;
1650
1651 if (surfaceFlags & SVGA3D_SURFACE_BIND_VERTEX_BUFFER) BindFlags |= D3D11_BIND_VERTEX_BUFFER;
1652 if (surfaceFlags & SVGA3D_SURFACE_BIND_INDEX_BUFFER) BindFlags |= D3D11_BIND_INDEX_BUFFER;
1653 if (surfaceFlags & SVGA3D_SURFACE_BIND_CONSTANT_BUFFER) BindFlags |= D3D11_BIND_CONSTANT_BUFFER;
1654 if (surfaceFlags & SVGA3D_SURFACE_BIND_SHADER_RESOURCE) BindFlags |= D3D11_BIND_SHADER_RESOURCE;
1655 if (surfaceFlags & SVGA3D_SURFACE_BIND_RENDER_TARGET) BindFlags |= D3D11_BIND_RENDER_TARGET;
1656 if (surfaceFlags & SVGA3D_SURFACE_BIND_DEPTH_STENCIL) BindFlags |= D3D11_BIND_DEPTH_STENCIL;
1657 if (surfaceFlags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) BindFlags |= D3D11_BIND_STREAM_OUTPUT;
1658 if (surfaceFlags & SVGA3D_SURFACE_BIND_UAVIEW) BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
1659
1660 return BindFlags;
1661}
1662
1663
1664static int vmsvga3dBackSurfaceCreateTexture(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
1665{
1666 PVMSVGA3DSTATE p3dState = pThisCC->svga.p3dState;
1667 AssertReturn(p3dState, VERR_INVALID_STATE);
1668
1669 PVMSVGA3DBACKEND pBackend = p3dState->pBackend;
1670 AssertReturn(pBackend, VERR_INVALID_STATE);
1671
1672 UINT MiscFlags;
1673 DXDEVICE *pDXDevice;
1674 if (dxIsSurfaceShareable(pSurface))
1675 {
1676 pDXDevice = &pBackend->device;
1677 MiscFlags = D3D11_RESOURCE_MISC_SHARED;
1678 }
1679 else
1680 {
1681 pDXDevice = &pDXContext->pBackendDXContext->device;
1682 MiscFlags = 0;
1683 }
1684 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
1685
1686 if (pSurface->pBackendSurface != NULL)
1687 {
1688 AssertFailed(); /** @todo Should the function not be used like that? */
1689 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
1690 }
1691
1692 PVMSVGA3DBACKENDSURFACE pBackendSurface;
1693 int rc = dxBackendSurfaceAlloc(&pBackendSurface);
1694 AssertRCReturn(rc, rc);
1695
1696 uint32_t const cWidth = pSurface->paMipmapLevels[0].mipmapSize.width;
1697 uint32_t const cHeight = pSurface->paMipmapLevels[0].mipmapSize.height;
1698 uint32_t const cDepth = pSurface->paMipmapLevels[0].mipmapSize.depth;
1699 uint32_t const numMipLevels = pSurface->cLevels;
1700
1701 DXGI_FORMAT dxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(pSurface->format);
1702 AssertReturn(dxgiFormat != DXGI_FORMAT_UNKNOWN, E_FAIL);
1703
1704 /*
1705 * Create D3D11 texture object.
1706 */
1707 HRESULT hr = S_OK;
1708 if (pSurface->surfaceFlags & SVGA3D_SURFACE_SCREENTARGET)
1709 {
1710 /*
1711 * Create the texture in backend device and open for the specified context.
1712 */
1713 D3D11_TEXTURE2D_DESC td;
1714 RT_ZERO(td);
1715 td.Width = pSurface->paMipmapLevels[0].mipmapSize.width;
1716 td.Height = pSurface->paMipmapLevels[0].mipmapSize.height;
1717 Assert(pSurface->cLevels == 1);
1718 td.MipLevels = 1;
1719 td.ArraySize = 1;
1720 td.Format = dxgiFormat;
1721 td.SampleDesc.Count = 1;
1722 td.SampleDesc.Quality = 0;
1723 td.Usage = D3D11_USAGE_DEFAULT;
1724 td.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
1725 td.CPUAccessFlags = 0;
1726 td.MiscFlags = MiscFlags;
1727
1728 hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->u.pTexture2D);
1729 Assert(SUCCEEDED(hr));
1730 if (SUCCEEDED(hr))
1731 {
1732 /* Map-able texture. */
1733 td.Usage = D3D11_USAGE_DYNAMIC;
1734 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
1735 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1736 td.MiscFlags = 0;
1737 hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->pDynamicTexture);
1738 Assert(SUCCEEDED(hr));
1739 }
1740
1741 if (SUCCEEDED(hr))
1742 {
1743 /* Staging texture. */
1744 td.Usage = D3D11_USAGE_STAGING;
1745 td.BindFlags = 0; /* No flags allowed. */
1746 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
1747 hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->pStagingTexture);
1748 Assert(SUCCEEDED(hr));
1749 }
1750
1751 if (SUCCEEDED(hr))
1752 {
1753 /* Get the shared handle. */
1754 IDXGIResource *pDxgiResource = NULL;
1755 hr = pBackendSurface->u.pTexture2D->QueryInterface(__uuidof(IDXGIResource), (void**)&pDxgiResource);
1756 Assert(SUCCEEDED(hr));
1757 if (SUCCEEDED(hr))
1758 {
1759 hr = pDxgiResource->GetSharedHandle(&pBackendSurface->SharedHandle);
1760 Assert(SUCCEEDED(hr));
1761 D3D_RELEASE(pDxgiResource);
1762 }
1763 }
1764
1765 if (SUCCEEDED(hr))
1766 {
1767 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_SCREEN_TARGET;
1768 }
1769 }
1770 else if (pSurface->surfaceFlags & SVGA3D_SURFACE_CUBEMAP)
1771 {
1772 Assert(pSurface->cFaces == 6);
1773 Assert(cWidth == cHeight);
1774 Assert(cDepth == 1);
1775//DEBUG_BREAKPOINT_TEST();
1776 D3D11_SUBRESOURCE_DATA *paInitialData = NULL;
1777 D3D11_SUBRESOURCE_DATA aInitialData[6 * SVGA3D_MAX_MIP_LEVELS];
1778 if (pSurface->paMipmapLevels[0].pSurfaceData)
1779 {
1780 /** @todo Can happen for a non GBO surface or if GBO texture was updated prior to creation if the hardware resource. Test this. */
1781 /** @todo for (i = 0; i < pSurface->cFaces * numMipLevels; ++i) */
1782 for (uint32_t iFace = 0; iFace < 6; ++iFace)
1783 {
1784 for (uint32_t i = 0; i < numMipLevels; ++i)
1785 {
1786 uint32_t const iSubresource = vmsvga3dCalcSubresource(i, iFace, numMipLevels);
1787
1788 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[iSubresource];
1789 D3D11_SUBRESOURCE_DATA *p = &aInitialData[iSubresource];
1790 p->pSysMem = pMipmapLevel->pSurfaceData;
1791 p->SysMemPitch = pMipmapLevel->cbSurfacePitch;
1792 p->SysMemSlicePitch = pMipmapLevel->cbSurfacePlane;
1793 }
1794 }
1795 paInitialData = &aInitialData[0];
1796 }
1797
1798 D3D11_TEXTURE2D_DESC td;
1799 RT_ZERO(td);
1800 td.Width = cWidth;
1801 td.Height = cHeight;
1802 td.MipLevels = numMipLevels;
1803 td.ArraySize = 6;
1804 td.Format = dxgiFormat;
1805 td.SampleDesc.Count = 1;
1806 td.SampleDesc.Quality = 0;
1807 td.Usage = D3D11_USAGE_DEFAULT;
1808 td.BindFlags = dxBindFlags(pSurface->surfaceFlags);
1809 td.CPUAccessFlags = 0; /** @todo */
1810 td.MiscFlags = MiscFlags | D3D11_RESOURCE_MISC_TEXTURECUBE; /** @todo */
1811 if ( numMipLevels > 1
1812 && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
1813 td.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
1814
1815 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->u.pTexture2D);
1816 Assert(SUCCEEDED(hr));
1817 if (SUCCEEDED(hr))
1818 {
1819 /* Map-able texture. */
1820 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
1821 td.ArraySize = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
1822 td.Usage = D3D11_USAGE_DYNAMIC;
1823 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
1824 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1825 td.MiscFlags = 0;
1826 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->pDynamicTexture);
1827 Assert(SUCCEEDED(hr));
1828 }
1829
1830 if (SUCCEEDED(hr))
1831 {
1832 /* Staging texture. */
1833 td.Usage = D3D11_USAGE_STAGING;
1834 td.BindFlags = 0; /* No flags allowed. */
1835 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
1836 td.MiscFlags = 0;
1837 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->pStagingTexture);
1838 Assert(SUCCEEDED(hr));
1839 }
1840
1841 if ( SUCCEEDED(hr)
1842 && MiscFlags == D3D11_RESOURCE_MISC_SHARED)
1843 {
1844 /* Get the shared handle. */
1845 IDXGIResource *pDxgiResource = NULL;
1846 hr = pBackendSurface->u.pTexture2D->QueryInterface(__uuidof(IDXGIResource), (void**)&pDxgiResource);
1847 Assert(SUCCEEDED(hr));
1848 if (SUCCEEDED(hr))
1849 {
1850 hr = pDxgiResource->GetSharedHandle(&pBackendSurface->SharedHandle);
1851 Assert(SUCCEEDED(hr));
1852 D3D_RELEASE(pDxgiResource);
1853 }
1854 }
1855
1856 if (SUCCEEDED(hr))
1857 {
1858 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_CUBE_TEXTURE;
1859 }
1860 }
1861 else if (pSurface->surfaceFlags & SVGA3D_SURFACE_1D)
1862 {
1863 AssertFailed(); /** @todo implement */
1864 hr = E_FAIL;
1865 }
1866 else
1867 {
1868 if (cDepth > 1)
1869 {
1870 /*
1871 * Volume texture.
1872 */
1873 Assert(pSurface->cFaces == 1);
1874
1875 D3D11_SUBRESOURCE_DATA *paInitialData = NULL;
1876 D3D11_SUBRESOURCE_DATA aInitialData[SVGA3D_MAX_MIP_LEVELS];
1877 if (pSurface->paMipmapLevels[0].pSurfaceData)
1878 {
1879 /** @todo Can happen for a non GBO surface or if GBO texture was updated prior to creation if the hardware resource. Test this. */
1880 for (uint32_t i = 0; i < numMipLevels; ++i)
1881 {
1882 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[i];
1883 D3D11_SUBRESOURCE_DATA *p = &aInitialData[i];
1884 p->pSysMem = pMipmapLevel->pSurfaceData;
1885 p->SysMemPitch = pMipmapLevel->cbSurfacePitch;
1886 p->SysMemSlicePitch = pMipmapLevel->cbSurfacePlane;
1887 }
1888 paInitialData = &aInitialData[0];
1889 }
1890
1891 D3D11_TEXTURE3D_DESC td;
1892 RT_ZERO(td);
1893 td.Width = cWidth;
1894 td.Height = cHeight;
1895 td.Depth = cDepth;
1896 td.MipLevels = numMipLevels;
1897 td.Format = dxgiFormat;
1898 td.Usage = D3D11_USAGE_DEFAULT;
1899 td.BindFlags = dxBindFlags(pSurface->surfaceFlags);
1900 td.CPUAccessFlags = 0; /** @todo */
1901 td.MiscFlags = MiscFlags; /** @todo */
1902 if ( numMipLevels > 1
1903 && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
1904 td.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
1905
1906 hr = pDXDevice->pDevice->CreateTexture3D(&td, paInitialData, &pBackendSurface->u.pTexture3D);
1907 Assert(SUCCEEDED(hr));
1908 if (SUCCEEDED(hr))
1909 {
1910 /* Map-able texture. */
1911 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
1912 td.Usage = D3D11_USAGE_DYNAMIC;
1913 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
1914 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1915 td.MiscFlags = 0;
1916 hr = pDXDevice->pDevice->CreateTexture3D(&td, paInitialData, &pBackendSurface->pDynamicTexture3D);
1917 Assert(SUCCEEDED(hr));
1918 }
1919
1920 if (SUCCEEDED(hr))
1921 {
1922 /* Staging texture. */
1923 td.Usage = D3D11_USAGE_STAGING;
1924 td.BindFlags = 0; /* No flags allowed. */
1925 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
1926 td.MiscFlags = 0;
1927 hr = pDXDevice->pDevice->CreateTexture3D(&td, paInitialData, &pBackendSurface->pStagingTexture3D);
1928 Assert(SUCCEEDED(hr));
1929 }
1930
1931 if ( SUCCEEDED(hr)
1932 && MiscFlags == D3D11_RESOURCE_MISC_SHARED)
1933 {
1934 /* Get the shared handle. */
1935 IDXGIResource *pDxgiResource = NULL;
1936 hr = pBackendSurface->u.pTexture3D->QueryInterface(__uuidof(IDXGIResource), (void**)&pDxgiResource);
1937 Assert(SUCCEEDED(hr));
1938 if (SUCCEEDED(hr))
1939 {
1940 hr = pDxgiResource->GetSharedHandle(&pBackendSurface->SharedHandle);
1941 Assert(SUCCEEDED(hr));
1942 D3D_RELEASE(pDxgiResource);
1943 }
1944 }
1945
1946 if (SUCCEEDED(hr))
1947 {
1948 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE_3D;
1949 }
1950 }
1951 else
1952 {
1953 /*
1954 * 2D texture.
1955 */
1956 Assert(pSurface->cFaces == 1);
1957
1958 D3D11_SUBRESOURCE_DATA *paInitialData = NULL;
1959 D3D11_SUBRESOURCE_DATA aInitialData[SVGA3D_MAX_MIP_LEVELS];
1960 if (pSurface->paMipmapLevels[0].pSurfaceData)
1961 {
1962 /** @todo Can happen for a non GBO surface or if GBO texture was updated prior to creation if the hardware resource. Test this. */
1963 for (uint32_t i = 0; i < numMipLevels; ++i)
1964 {
1965 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[i];
1966 D3D11_SUBRESOURCE_DATA *p = &aInitialData[i];
1967 p->pSysMem = pMipmapLevel->pSurfaceData;
1968 p->SysMemPitch = pMipmapLevel->cbSurfacePitch;
1969 p->SysMemSlicePitch = pMipmapLevel->cbSurfacePlane;
1970 }
1971 paInitialData = &aInitialData[0];
1972 }
1973
1974 D3D11_TEXTURE2D_DESC td;
1975 RT_ZERO(td);
1976 td.Width = cWidth;
1977 td.Height = cHeight;
1978 td.MipLevels = numMipLevels;
1979 td.ArraySize = 1; /** @todo */
1980 td.Format = dxgiFormat;
1981 td.SampleDesc.Count = 1;
1982 td.SampleDesc.Quality = 0;
1983 td.Usage = D3D11_USAGE_DEFAULT;
1984 td.BindFlags = dxBindFlags(pSurface->surfaceFlags);
1985 td.CPUAccessFlags = 0; /** @todo */
1986 td.MiscFlags = MiscFlags; /** @todo */
1987 if ( numMipLevels > 1
1988 && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
1989 td.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
1990
1991 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->u.pTexture2D);
1992 Assert(SUCCEEDED(hr));
1993 if (SUCCEEDED(hr))
1994 {
1995 /* Map-able texture. */
1996 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
1997 td.Usage = D3D11_USAGE_DYNAMIC;
1998 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
1999 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2000 td.MiscFlags = 0;
2001 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->pDynamicTexture);
2002 Assert(SUCCEEDED(hr));
2003 }
2004
2005 if (SUCCEEDED(hr))
2006 {
2007 /* Staging texture. */
2008 td.Usage = D3D11_USAGE_STAGING;
2009 td.BindFlags = 0; /* No flags allowed. */
2010 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2011 td.MiscFlags = 0;
2012 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->pStagingTexture);
2013 Assert(SUCCEEDED(hr));
2014 }
2015
2016 if ( SUCCEEDED(hr)
2017 && MiscFlags == D3D11_RESOURCE_MISC_SHARED)
2018 {
2019 /* Get the shared handle. */
2020 IDXGIResource *pDxgiResource = NULL;
2021 hr = pBackendSurface->u.pTexture2D->QueryInterface(__uuidof(IDXGIResource), (void**)&pDxgiResource);
2022 Assert(SUCCEEDED(hr));
2023 if (SUCCEEDED(hr))
2024 {
2025 hr = pDxgiResource->GetSharedHandle(&pBackendSurface->SharedHandle);
2026 Assert(SUCCEEDED(hr));
2027 D3D_RELEASE(pDxgiResource);
2028 }
2029 }
2030
2031 if (SUCCEEDED(hr))
2032 {
2033 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE;
2034 }
2035 }
2036 }
2037
2038 Assert(hr == S_OK);
2039
2040 if (pSurface->autogenFilter != SVGA3D_TEX_FILTER_NONE)
2041 {
2042 }
2043
2044 if (SUCCEEDED(hr))
2045 {
2046 /*
2047 * Success.
2048 */
2049 LogFunc(("sid = %u\n", pSurface->id));
2050 pBackendSurface->enmDxgiFormat = dxgiFormat;
2051 pSurface->pBackendSurface = pBackendSurface;
2052 if (RT_BOOL(MiscFlags & D3D11_RESOURCE_MISC_SHARED))
2053 pSurface->idAssociatedContext = DX_CID_BACKEND;
2054 else
2055 pSurface->idAssociatedContext = pDXContext->cid;
2056 return VINF_SUCCESS;
2057 }
2058
2059 /** @todo different enmResType Failure. */
2060 D3D_RELEASE(pBackendSurface->pStagingTexture);
2061 D3D_RELEASE(pBackendSurface->pDynamicTexture);
2062 D3D_RELEASE(pBackendSurface->u.pTexture2D);
2063 RTMemFree(pBackendSurface);
2064 return VERR_NO_MEMORY;
2065}
2066
2067
2068/** @todo This is practically the same code as vmsvga3dBackSurfaceCreateTexture */
2069static int vmsvga3dBackSurfaceCreateDepthStencilTexture(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
2070{
2071 DXDEVICE *pDXDevice = &pDXContext->pBackendDXContext->device;
2072 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
2073
2074 if (pSurface->pBackendSurface != NULL)
2075 {
2076 AssertFailed(); /** @todo Should the function not be used like that? */
2077 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
2078 }
2079
2080 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2081 int rc = dxBackendSurfaceAlloc(&pBackendSurface);
2082 AssertRCReturn(rc, rc);
2083
2084 uint32_t const cWidth = pSurface->paMipmapLevels[0].mipmapSize.width;
2085 uint32_t const cHeight = pSurface->paMipmapLevels[0].mipmapSize.height;
2086 uint32_t const cDepth = pSurface->paMipmapLevels[0].mipmapSize.depth;
2087 uint32_t const numMipLevels = pSurface->cLevels;
2088
2089 DXGI_FORMAT dxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(pSurface->format);
2090 AssertReturn(dxgiFormat != DXGI_FORMAT_UNKNOWN, E_FAIL);
2091
2092 /*
2093 * Create D3D11 texture object.
2094 */
2095 HRESULT hr = S_OK;
2096 if (pSurface->surfaceFlags & SVGA3D_SURFACE_CUBEMAP)
2097 {
2098 AssertFailed(); /** @todo implement */
2099 hr = E_FAIL;
2100 }
2101 else if (pSurface->surfaceFlags & SVGA3D_SURFACE_1D)
2102 {
2103 AssertFailed(); /** @todo implement */
2104 hr = E_FAIL;
2105 }
2106 else
2107 {
2108 if (cDepth > 1)
2109 {
2110 AssertFailed(); /** @todo implement */
2111 hr = E_FAIL;
2112 }
2113 else
2114 {
2115 /*
2116 * 2D texture.
2117 */
2118 Assert(pSurface->cFaces == 1);
2119
2120 D3D11_SUBRESOURCE_DATA *paInitialData = NULL;
2121 D3D11_SUBRESOURCE_DATA aInitialData[SVGA3D_MAX_MIP_LEVELS];
2122 if (pSurface->paMipmapLevels[0].pSurfaceData)
2123 {
2124 /** @todo Can happen for a non GBO surface or if GBO texture was updated prior to creation if the hardware resource. Test this. */
2125 for (uint32_t i = 0; i < numMipLevels; ++i)
2126 {
2127 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[i];
2128 D3D11_SUBRESOURCE_DATA *p = &aInitialData[i];
2129 p->pSysMem = pMipmapLevel->pSurfaceData;
2130 p->SysMemPitch = pMipmapLevel->cbSurfacePitch;
2131 p->SysMemSlicePitch = pMipmapLevel->cbSurfacePlane;
2132 }
2133 paInitialData = &aInitialData[0];
2134 }
2135
2136 D3D11_TEXTURE2D_DESC td;
2137 RT_ZERO(td);
2138 td.Width = cWidth;
2139 td.Height = cHeight;
2140 Assert(pSurface->cLevels == 1);
2141 td.MipLevels = 1;
2142 td.ArraySize = 1;
2143 td.Format = dxgiFormat;
2144 td.SampleDesc.Count = 1;
2145 td.SampleDesc.Quality = 0;
2146 td.Usage = D3D11_USAGE_DEFAULT;
2147 td.BindFlags = dxBindFlags(pSurface->surfaceFlags);
2148 td.CPUAccessFlags = 0;
2149 td.MiscFlags = 0;
2150
2151 hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->u.pTexture2D);
2152 Assert(SUCCEEDED(hr));
2153 if (SUCCEEDED(hr))
2154 {
2155 /* Map-able texture. */
2156 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2157 td.Usage = D3D11_USAGE_DYNAMIC;
2158 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2159 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2160 td.MiscFlags = 0;
2161 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->pDynamicTexture);
2162 Assert(SUCCEEDED(hr));
2163 }
2164
2165 if (SUCCEEDED(hr))
2166 {
2167 /* Staging texture. */
2168 td.Usage = D3D11_USAGE_STAGING;
2169 td.BindFlags = 0; /* No flags allowed. */
2170 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2171 td.MiscFlags = 0;
2172 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->pStagingTexture);
2173 Assert(SUCCEEDED(hr));
2174 }
2175
2176 if (SUCCEEDED(hr))
2177 {
2178 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE;
2179 }
2180 }
2181 }
2182
2183 if (SUCCEEDED(hr))
2184 {
2185 /*
2186 * Success.
2187 */
2188 pBackendSurface->enmDxgiFormat = dxgiFormat;
2189 pSurface->pBackendSurface = pBackendSurface;
2190 pSurface->idAssociatedContext = pDXContext->cid;
2191 return VINF_SUCCESS;
2192 }
2193
2194 /** @todo different enmResType Failure. */
2195 D3D_RELEASE(pBackendSurface->pStagingTexture);
2196 D3D_RELEASE(pBackendSurface->pDynamicTexture);
2197 D3D_RELEASE(pBackendSurface->u.pTexture2D);
2198 RTMemFree(pBackendSurface);
2199 return VERR_NO_MEMORY;
2200}
2201
2202
2203static int vmsvga3dBackSurfaceCreateBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
2204{
2205 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
2206 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
2207
2208 /* Buffers should be created as such. */
2209 AssertReturn(RT_BOOL(pSurface->surfaceFlags & ( SVGA3D_SURFACE_HINT_INDEXBUFFER
2210 | SVGA3D_SURFACE_HINT_VERTEXBUFFER
2211 | SVGA3D_SURFACE_BIND_VERTEX_BUFFER
2212 | SVGA3D_SURFACE_BIND_INDEX_BUFFER
2213 )), VERR_INVALID_PARAMETER);
2214
2215 if (pSurface->pBackendSurface != NULL)
2216 {
2217 AssertFailed(); /** @todo Should the function not be used like that? */
2218 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
2219 }
2220
2221 PVMSVGA3DMIPMAPLEVEL pMipLevel;
2222 int rc = vmsvga3dMipmapLevel(pSurface, 0, 0, &pMipLevel);
2223 AssertRCReturn(rc, rc);
2224
2225 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2226 rc = dxBackendSurfaceAlloc(&pBackendSurface);
2227 AssertRCReturn(rc, rc);
2228
2229 /* Upload the current data, if any. */
2230 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
2231 D3D11_SUBRESOURCE_DATA initialData;
2232 if (pMipLevel->pSurfaceData)
2233 {
2234 initialData.pSysMem = pMipLevel->pSurfaceData;
2235 initialData.SysMemPitch = pMipLevel->cbSurface;
2236 initialData.SysMemSlicePitch = pMipLevel->cbSurface;
2237
2238 pInitialData = &initialData;
2239
2240 pMipLevel->fDirty = false;
2241 pSurface->fDirty = false;
2242 }
2243
2244 D3D11_BUFFER_DESC bd;
2245 RT_ZERO(bd);
2246 bd.ByteWidth = pMipLevel->cbSurface;
2247 bd.Usage = D3D11_USAGE_DEFAULT;
2248 bd.BindFlags = D3D11_BIND_VERTEX_BUFFER
2249 | D3D11_BIND_INDEX_BUFFER;
2250
2251 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.pBuffer);
2252 if (SUCCEEDED(hr))
2253 {
2254 /*
2255 * Success.
2256 */
2257 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
2258 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
2259 pSurface->pBackendSurface = pBackendSurface;
2260 pSurface->idAssociatedContext = pDXContext->cid;
2261 return VINF_SUCCESS;
2262 }
2263
2264 /* Failure. */
2265 D3D_RELEASE(pBackendSurface->u.pBuffer);
2266 RTMemFree(pBackendSurface);
2267 return VERR_NO_MEMORY;
2268}
2269
2270
2271static int vmsvga3dBackSurfaceCreateSoBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
2272{
2273 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
2274 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
2275
2276 /* Buffers should be created as such. */
2277 AssertReturn(RT_BOOL(pSurface->surfaceFlags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT), VERR_INVALID_PARAMETER);
2278
2279 if (pSurface->pBackendSurface != NULL)
2280 {
2281 AssertFailed(); /** @todo Should the function not be used like that? */
2282 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
2283 }
2284
2285 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2286 int rc = dxBackendSurfaceAlloc(&pBackendSurface);
2287 AssertRCReturn(rc, rc);
2288
2289 D3D11_BUFFER_DESC bd;
2290 RT_ZERO(bd);
2291 bd.ByteWidth = pSurface->paMipmapLevels[0].cbSurface;
2292 bd.Usage = D3D11_USAGE_DEFAULT;
2293 bd.BindFlags = dxBindFlags(pSurface->surfaceFlags); // D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_OUTPUT;
2294 bd.CPUAccessFlags = 0; /// @todo ? D3D11_CPU_ACCESS_READ;
2295 bd.MiscFlags = 0;
2296 bd.StructureByteStride = 0;
2297
2298 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, 0, &pBackendSurface->u.pBuffer);
2299 if (SUCCEEDED(hr))
2300 {
2301 /*
2302 * Success.
2303 */
2304 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
2305 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
2306 pSurface->pBackendSurface = pBackendSurface;
2307 pSurface->idAssociatedContext = pDXContext->cid;
2308 pSurface->fDirty = true;
2309 return VINF_SUCCESS;
2310 }
2311
2312 /* Failure. */
2313 D3D_RELEASE(pBackendSurface->u.pBuffer);
2314 RTMemFree(pBackendSurface);
2315 return VERR_NO_MEMORY;
2316}
2317
2318/** @todo Not needed */
2319static int vmsvga3dBackSurfaceCreateConstantBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
2320{
2321 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
2322 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
2323
2324 /* Buffers should be created as such. */
2325 AssertReturn(RT_BOOL(pSurface->surfaceFlags & ( SVGA3D_SURFACE_BIND_CONSTANT_BUFFER)), VERR_INVALID_PARAMETER);
2326
2327 if (pSurface->pBackendSurface != NULL)
2328 {
2329 AssertFailed(); /** @todo Should the function not be used like that? */
2330 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
2331 }
2332
2333 PVMSVGA3DMIPMAPLEVEL pMipLevel;
2334 int rc = vmsvga3dMipmapLevel(pSurface, 0, 0, &pMipLevel);
2335 AssertRCReturn(rc, rc);
2336
2337 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2338 rc = dxBackendSurfaceAlloc(&pBackendSurface);
2339 AssertRCReturn(rc, rc);
2340
2341 /* Upload the current data, if any. */
2342 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
2343 D3D11_SUBRESOURCE_DATA initialData;
2344 if (pMipLevel->pSurfaceData)
2345 {
2346 initialData.pSysMem = pMipLevel->pSurfaceData;
2347 initialData.SysMemPitch = pMipLevel->cbSurface;
2348 initialData.SysMemSlicePitch = pMipLevel->cbSurface;
2349
2350 pInitialData = &initialData;
2351
2352 pMipLevel->fDirty = false;
2353 pSurface->fDirty = false;
2354 }
2355
2356 D3D11_BUFFER_DESC bd;
2357 RT_ZERO(bd);
2358 bd.ByteWidth = pMipLevel->cbSurface;
2359 bd.Usage = D3D11_USAGE_DYNAMIC;
2360 bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
2361 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2362 bd.MiscFlags = 0;
2363 bd.StructureByteStride = 0;
2364
2365 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.pBuffer);
2366 if (SUCCEEDED(hr))
2367 {
2368 /*
2369 * Success.
2370 */
2371 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
2372 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
2373 pSurface->pBackendSurface = pBackendSurface;
2374 pSurface->idAssociatedContext = pDXContext->cid;
2375 return VINF_SUCCESS;
2376 }
2377
2378 /* Failure. */
2379 D3D_RELEASE(pBackendSurface->u.pBuffer);
2380 RTMemFree(pBackendSurface);
2381 return VERR_NO_MEMORY;
2382}
2383
2384
2385static HRESULT dxCreateConstantBuffer(DXDEVICE *pDevice, VMSVGA3DSURFACE const *pSurface, PVMSVGA3DBACKENDSURFACE pBackendSurface)
2386{
2387 D3D11_SUBRESOURCE_DATA *pInitialData = NULL; /** @todo */
2388 D3D11_BUFFER_DESC bd;
2389 RT_ZERO(bd);
2390 bd.ByteWidth = pSurface->paMipmapLevels[0].cbSurface;
2391 bd.Usage = D3D11_USAGE_DYNAMIC; /** @todo HINT_STATIC */
2392 bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
2393 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2394 bd.MiscFlags = 0;
2395 bd.StructureByteStride = 0;
2396
2397 return pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.pBuffer);
2398}
2399
2400
2401static HRESULT dxCreateBuffer(DXDEVICE *pDevice, VMSVGA3DSURFACE const *pSurface, PVMSVGA3DBACKENDSURFACE pBackendSurface)
2402{
2403 D3D11_SUBRESOURCE_DATA *pInitialData = NULL; /** @todo */
2404 D3D11_BUFFER_DESC bd;
2405 RT_ZERO(bd);
2406 bd.ByteWidth = pSurface->paMipmapLevels[0].cbSurface;
2407 bd.Usage = D3D11_USAGE_DYNAMIC; /** @todo HINT_STATIC */
2408 bd.BindFlags = D3D11_BIND_VERTEX_BUFFER
2409 | D3D11_BIND_INDEX_BUFFER;
2410 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2411 bd.MiscFlags = 0;
2412 bd.StructureByteStride = 0;
2413
2414 return pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.pBuffer);
2415}
2416
2417/** @todo Not needed? */
2418static int vmsvga3dBackSurfaceCreate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
2419{
2420 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
2421 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
2422
2423 if (pSurface->pBackendSurface != NULL)
2424 {
2425 AssertFailed(); /** @todo Should the function not be used like that? */
2426 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
2427 }
2428
2429 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2430 int rc = dxBackendSurfaceAlloc(&pBackendSurface);
2431 AssertRCReturn(rc, rc);
2432
2433 HRESULT hr;
2434
2435 /*
2436 * Figure out the type of the surface.
2437 */
2438 if (pSurface->surfaceFlags & SVGA3D_SURFACE_BIND_CONSTANT_BUFFER)
2439 {
2440 hr = dxCreateConstantBuffer(pDevice, pSurface, pBackendSurface);
2441 if (SUCCEEDED(hr))
2442 {
2443 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
2444 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
2445 }
2446 else
2447 D3D_RELEASE(pBackendSurface->u.pBuffer);
2448 }
2449 else if (pSurface->surfaceFlags & ( SVGA3D_SURFACE_BIND_VERTEX_BUFFER
2450 | SVGA3D_SURFACE_BIND_INDEX_BUFFER
2451 | SVGA3D_SURFACE_HINT_VERTEXBUFFER
2452 | SVGA3D_SURFACE_HINT_INDEXBUFFER))
2453 {
2454 hr = dxCreateBuffer(pDevice, pSurface, pBackendSurface);
2455 if (SUCCEEDED(hr))
2456 {
2457 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
2458 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
2459 }
2460 else
2461 D3D_RELEASE(pBackendSurface->u.pBuffer);
2462 }
2463 else
2464 {
2465 AssertFailed(); /** @todo implement */
2466 hr = E_FAIL;
2467 }
2468
2469 if (SUCCEEDED(hr))
2470 {
2471 /*
2472 * Success.
2473 */
2474 pSurface->pBackendSurface = pBackendSurface;
2475 pSurface->idAssociatedContext = pDXContext->cid;
2476 return VINF_SUCCESS;
2477 }
2478
2479 /* Failure. */
2480 RTMemFree(pBackendSurface);
2481 return VERR_NO_MEMORY;
2482}
2483
2484
2485static int dxStagingBufferRealloc(DXDEVICE *pDXDevice, uint32_t cbRequiredSize)
2486{
2487 AssertReturn(cbRequiredSize < SVGA3D_MAX_SURFACE_MEM_SIZE, VERR_INVALID_PARAMETER);
2488
2489 if (RT_LIKELY(cbRequiredSize <= pDXDevice->cbStagingBuffer))
2490 return VINF_SUCCESS;
2491
2492 D3D_RELEASE(pDXDevice->pStagingBuffer);
2493
2494 uint32_t const cbAlloc = RT_ALIGN_32(cbRequiredSize, _64K);
2495
2496 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
2497 D3D11_BUFFER_DESC bd;
2498 RT_ZERO(bd);
2499 bd.ByteWidth = cbAlloc;
2500 bd.Usage = D3D11_USAGE_STAGING;
2501 //bd.BindFlags = 0; /* No bind flags are allowed for staging resources. */
2502 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
2503
2504 int rc = VINF_SUCCESS;
2505 ID3D11Buffer *pBuffer;
2506 HRESULT hr = pDXDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBuffer);
2507 if (SUCCEEDED(hr))
2508 {
2509 pDXDevice->pStagingBuffer = pBuffer;
2510 pDXDevice->cbStagingBuffer = cbAlloc;
2511 }
2512 else
2513 {
2514 pDXDevice->cbStagingBuffer = 0;
2515 rc = VERR_NO_MEMORY;
2516 }
2517
2518 return rc;
2519}
2520
2521
2522static DECLCALLBACK(int) vmsvga3dBackInit(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC)
2523{
2524 RT_NOREF(pDevIns, pThis);
2525
2526 PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)RTMemAllocZ(sizeof(VMSVGA3DSTATE));
2527 AssertReturn(pState, VERR_NO_MEMORY);
2528 pThisCC->svga.p3dState = pState;
2529
2530 PVMSVGA3DBACKEND pBackend = (PVMSVGA3DBACKEND)RTMemAllocZ(sizeof(VMSVGA3DBACKEND));
2531 AssertReturn(pBackend, VERR_NO_MEMORY);
2532 pState->pBackend = pBackend;
2533
2534 int rc = RTLdrLoadSystem("d3d11", /* fNoUnload = */ true, &pBackend->hD3D11);
2535 AssertRC(rc);
2536 if (RT_SUCCESS(rc))
2537 {
2538 rc = RTLdrGetSymbol(pBackend->hD3D11, "D3D11CreateDevice", (void **)&pBackend->pfnD3D11CreateDevice);
2539 AssertRC(rc);
2540 }
2541
2542 if (RT_SUCCESS(rc))
2543 {
2544 /* Failure to load the shader disassembler is ignored. */
2545 int rc2 = RTLdrLoadSystem("D3DCompiler_47", /* fNoUnload = */ true, &pBackend->hD3DCompiler);
2546 AssertRC(rc2);
2547 if (RT_SUCCESS(rc2))
2548 {
2549 rc2 = RTLdrGetSymbol(pBackend->hD3DCompiler, "D3DDisassemble", (void **)&pBackend->pfnD3DDisassemble);
2550 AssertRC(rc2);
2551 }
2552 Log6Func(("Load D3DDisassemble: %Rrc\n", rc2));
2553 }
2554//DEBUG_BREAKPOINT_TEST();
2555 return rc;
2556}
2557
2558
2559static DECLCALLBACK(int) vmsvga3dBackPowerOn(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC)
2560{
2561 RT_NOREF(pDevIns, pThis);
2562
2563 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
2564 AssertReturn(pState, VERR_INVALID_STATE);
2565
2566 PVMSVGA3DBACKEND pBackend = pState->pBackend;
2567 AssertReturn(pBackend, VERR_INVALID_STATE);
2568
2569 int rc = dxDeviceCreate(pBackend, &pBackend->device);
2570 return rc;
2571}
2572
2573
2574static DECLCALLBACK(int) vmsvga3dBackTerminate(PVGASTATECC pThisCC)
2575{
2576 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
2577 AssertReturn(pState, VERR_INVALID_STATE);
2578
2579 if (pState->pBackend)
2580 {
2581 /** @todo Clean up backends. */
2582
2583 dxDeviceDestroy(pState->pBackend, &pState->pBackend->device);
2584
2585 RTMemFree(pState->pBackend);
2586 pState->pBackend = NULL;
2587 }
2588
2589 return VINF_SUCCESS;
2590}
2591
2592
2593static DECLCALLBACK(int) vmsvga3dBackReset(PVGASTATECC pThisCC)
2594{
2595 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
2596 AssertReturn(pState, VERR_INVALID_STATE);
2597
2598 /** @todo Cleanup all resources and recreate Device, ImmediateContext etc to be at the same state as after poweron. */
2599
2600 return VINF_SUCCESS;
2601}
2602
2603
2604static int vmsvga3dDrvNotifyDefineScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
2605{
2606 /** @todo Such structures must be in VBoxVideo3D.h */
2607 typedef struct VBOX3DNOTIFYDEFINESCREEN
2608 {
2609 VBOX3DNOTIFY Core;
2610 uint32_t cWidth;
2611 uint32_t cHeight;
2612 int32_t xRoot;
2613 int32_t yRoot;
2614 uint32_t fPrimary;
2615 uint32_t cDpi;
2616 } VBOX3DNOTIFYDEFINESCREEN;
2617
2618 VBOX3DNOTIFYDEFINESCREEN n;
2619 n.Core.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_CREATED;
2620 n.Core.iDisplay = pScreen->idScreen;
2621 n.Core.u32Reserved = 0;
2622 n.Core.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
2623 RT_ZERO(n.Core.au8Data);
2624 n.cWidth = pScreen->cWidth;
2625 n.cHeight = pScreen->cHeight;
2626 n.xRoot = pScreen->xOrigin;
2627 n.yRoot = pScreen->yOrigin;
2628 n.fPrimary = RT_BOOL(pScreen->fuScreen & SVGA_SCREEN_IS_PRIMARY);
2629 n.cDpi = pScreen->cDpi;
2630
2631 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n.Core);
2632}
2633
2634
2635static int vmsvga3dDrvNotifyDestroyScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
2636{
2637 VBOX3DNOTIFY n;
2638 n.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_DESTROYED;
2639 n.iDisplay = pScreen->idScreen;
2640 n.u32Reserved = 0;
2641 n.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
2642 RT_ZERO(n.au8Data);
2643
2644 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n);
2645}
2646
2647
2648static int vmsvga3dDrvNotifyBindSurface(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, HANDLE hSharedSurface)
2649{
2650 VBOX3DNOTIFY n;
2651 n.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_BIND_SURFACE;
2652 n.iDisplay = pScreen->idScreen;
2653 n.u32Reserved = 0;
2654 n.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
2655 *(uint64_t *)&n.au8Data[0] = (uint64_t)hSharedSurface;
2656
2657 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n);
2658}
2659
2660
2661static int vmsvga3dDrvNotifyUpdate(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen,
2662 uint32_t x, uint32_t y, uint32_t w, uint32_t h)
2663{
2664 typedef struct VBOX3DNOTIFYUPDATE
2665 {
2666 VBOX3DNOTIFY Core;
2667 uint32_t x;
2668 uint32_t y;
2669 uint32_t w;
2670 uint32_t h;
2671 } VBOX3DNOTIFYUPDATE;
2672
2673 VBOX3DNOTIFYUPDATE n;
2674 n.Core.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_UPDATE_END;
2675 n.Core.iDisplay = pScreen->idScreen;
2676 n.Core.u32Reserved = 0;
2677 n.Core.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
2678 RT_ZERO(n.Core.au8Data);
2679 n.x = x;
2680 n.y = y;
2681 n.w = w;
2682 n.h = h;
2683
2684 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n.Core);
2685}
2686
2687static int vmsvga3dHwScreenCreate(PVMSVGA3DSTATE pState, uint32_t cWidth, uint32_t cHeight, VMSVGAHWSCREEN *p)
2688{
2689 PVMSVGA3DBACKEND pBackend = pState->pBackend;
2690
2691 DXDEVICE *pDXDevice = &pBackend->device;
2692 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
2693
2694 D3D11_TEXTURE2D_DESC td;
2695 RT_ZERO(td);
2696 td.Width = cWidth;
2697 td.Height = cHeight;
2698 td.MipLevels = 1;
2699 td.ArraySize = 1;
2700 td.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
2701 td.SampleDesc.Count = 1;
2702 td.SampleDesc.Quality = 0;
2703 td.Usage = D3D11_USAGE_DEFAULT;
2704 td.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
2705 td.CPUAccessFlags = 0;
2706 td.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
2707
2708 HRESULT hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &p->pTexture);
2709 if (SUCCEEDED(hr))
2710 {
2711 /* Get the shared handle. */
2712 hr = p->pTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&p->pDxgiResource);
2713 if (SUCCEEDED(hr))
2714 {
2715 hr = p->pDxgiResource->GetSharedHandle(&p->SharedHandle);
2716 if (SUCCEEDED(hr))
2717 hr = p->pTexture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)&p->pDXGIKeyedMutex);
2718 }
2719 }
2720
2721 if (SUCCEEDED(hr))
2722 return VINF_SUCCESS;
2723
2724 AssertFailed();
2725 return VERR_NOT_SUPPORTED;
2726}
2727
2728
2729static void vmsvga3dHwScreenDestroy(PVMSVGA3DSTATE pState, VMSVGAHWSCREEN *p)
2730{
2731 RT_NOREF(pState);
2732 D3D_RELEASE(p->pDXGIKeyedMutex);
2733 D3D_RELEASE(p->pDxgiResource);
2734 D3D_RELEASE(p->pTexture);
2735 p->SharedHandle = 0;
2736 p->sidScreenTarget = SVGA_ID_INVALID;
2737}
2738
2739
2740static DECLCALLBACK(int) vmsvga3dBackDefineScreen(PVGASTATE pThis, PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
2741{
2742 RT_NOREF(pThis, pThisCC, pScreen);
2743
2744 LogRel4(("VMSVGA: vmsvga3dBackDefineScreen: screen %u\n", pScreen->idScreen));
2745
2746 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
2747 AssertReturn(pState, VERR_INVALID_STATE);
2748
2749 PVMSVGA3DBACKEND pBackend = pState->pBackend;
2750 AssertReturn(pBackend, VERR_INVALID_STATE);
2751
2752 Assert(pScreen->pHwScreen == NULL);
2753
2754 VMSVGAHWSCREEN *p = (VMSVGAHWSCREEN *)RTMemAllocZ(sizeof(VMSVGAHWSCREEN));
2755 AssertPtrReturn(p, VERR_NO_MEMORY);
2756
2757 p->sidScreenTarget = SVGA_ID_INVALID;
2758
2759 int rc = vmsvga3dDrvNotifyDefineScreen(pThisCC, pScreen);
2760 if (RT_SUCCESS(rc))
2761 {
2762 /* The frontend supports the screen. Create the actual resource. */
2763 rc = vmsvga3dHwScreenCreate(pState, pScreen->cWidth, pScreen->cHeight, p);
2764 if (RT_SUCCESS(rc))
2765 LogRel4(("VMSVGA: vmsvga3dBackDefineScreen: created\n"));
2766 }
2767
2768 if (RT_SUCCESS(rc))
2769 {
2770 LogRel(("VMSVGA: Using HW accelerated screen %u\n", pScreen->idScreen));
2771 pScreen->pHwScreen = p;
2772 }
2773 else
2774 {
2775 LogRel4(("VMSVGA: vmsvga3dBackDefineScreen: %Rrc\n", rc));
2776 vmsvga3dHwScreenDestroy(pState, p);
2777 RTMemFree(p);
2778 }
2779
2780 return rc;
2781}
2782
2783
2784static DECLCALLBACK(int) vmsvga3dBackDestroyScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
2785{
2786 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
2787 AssertReturn(pState, VERR_INVALID_STATE);
2788
2789 vmsvga3dDrvNotifyDestroyScreen(pThisCC, pScreen);
2790
2791 if (pScreen->pHwScreen)
2792 {
2793 vmsvga3dHwScreenDestroy(pState, pScreen->pHwScreen);
2794 RTMemFree(pScreen->pHwScreen);
2795 pScreen->pHwScreen = NULL;
2796 }
2797
2798 return VINF_SUCCESS;
2799}
2800
2801
2802static DECLCALLBACK(int) vmsvga3dBackSurfaceBlitToScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen,
2803 SVGASignedRect destRect, SVGA3dSurfaceImageId srcImage,
2804 SVGASignedRect srcRect, uint32_t cRects, SVGASignedRect *paRects)
2805{
2806 RT_NOREF(pThisCC, pScreen, destRect, srcImage, srcRect, cRects, paRects);
2807
2808 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
2809 AssertReturn(pState, VERR_INVALID_STATE);
2810
2811 PVMSVGA3DBACKEND pBackend = pState->pBackend;
2812 AssertReturn(pBackend, VERR_INVALID_STATE);
2813
2814 VMSVGAHWSCREEN *p = pScreen->pHwScreen;
2815 AssertReturn(p, VERR_NOT_SUPPORTED);
2816
2817 PVMSVGA3DSURFACE pSurface;
2818 int rc = vmsvga3dSurfaceFromSid(pState, srcImage.sid, &pSurface);
2819 AssertRCReturn(rc, rc);
2820
2821 /** @todo Implement. */
2822 AssertFailed();
2823 return VERR_NOT_IMPLEMENTED;
2824}
2825
2826
2827static DECLCALLBACK(int) vmsvga3dBackSurfaceMap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, SVGA3dBox const *pBox,
2828 VMSVGA3D_SURFACE_MAP enmMapType, VMSVGA3D_MAPPED_SURFACE *pMap)
2829{
2830 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
2831 AssertReturn(pState, VERR_INVALID_STATE);
2832
2833 PVMSVGA3DBACKEND pBackend = pState->pBackend;
2834 AssertReturn(pBackend, VERR_INVALID_STATE);
2835
2836 PVMSVGA3DSURFACE pSurface;
2837 int rc = vmsvga3dSurfaceFromSid(pState, pImage->sid, &pSurface);
2838 AssertRCReturn(rc, rc);
2839
2840 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
2841 AssertPtrReturn(pBackendSurface, VERR_INVALID_STATE);
2842
2843 PVMSVGA3DMIPMAPLEVEL pMipLevel;
2844 rc = vmsvga3dMipmapLevel(pSurface, pImage->face, pImage->mipmap, &pMipLevel);
2845 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
2846
2847 /* A surface is always mapped by the DX context which has created the surface. */
2848 DXDEVICE *pDevice = dxDeviceFromCid(pSurface->idAssociatedContext, pState);
2849 AssertReturn(pDevice && pDevice->pDevice, VERR_INVALID_STATE);
2850
2851 SVGA3dBox clipBox;
2852 if (pBox)
2853 {
2854 clipBox = *pBox;
2855 vmsvgaR3ClipBox(&pMipLevel->mipmapSize, &clipBox);
2856 ASSERT_GUEST_RETURN(clipBox.w && clipBox.h && clipBox.d, VERR_INVALID_PARAMETER);
2857 }
2858 else
2859 {
2860 clipBox.x = 0;
2861 clipBox.y = 0;
2862 clipBox.z = 0;
2863 clipBox.w = pMipLevel->mipmapSize.width;
2864 clipBox.h = pMipLevel->mipmapSize.height;
2865 clipBox.d = pMipLevel->mipmapSize.depth;
2866 }
2867
2868 D3D11_MAP d3d11MapType;
2869 switch (enmMapType)
2870 {
2871 case VMSVGA3D_SURFACE_MAP_READ: d3d11MapType = D3D11_MAP_READ; break;
2872 case VMSVGA3D_SURFACE_MAP_WRITE: d3d11MapType = D3D11_MAP_WRITE; break;
2873 case VMSVGA3D_SURFACE_MAP_READ_WRITE: d3d11MapType = D3D11_MAP_READ_WRITE; break;
2874 case VMSVGA3D_SURFACE_MAP_WRITE_DISCARD: d3d11MapType = D3D11_MAP_WRITE_DISCARD; break;
2875 default:
2876 AssertFailed();
2877 return VERR_INVALID_PARAMETER;
2878 }
2879
2880 D3D11_MAPPED_SUBRESOURCE mappedResource;
2881 RT_ZERO(mappedResource);
2882
2883 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
2884 {
2885 Assert(pImage->face == 0 && pImage->mipmap == 0);
2886
2887 /* Wait for the surface to finish drawing. */
2888 dxSurfaceWait(pState, pSurface, pSurface->idAssociatedContext);
2889
2890 ID3D11Texture2D *pMappedTexture;
2891 if (enmMapType == VMSVGA3D_SURFACE_MAP_READ)
2892 {
2893 pMappedTexture = pBackendSurface->pStagingTexture;
2894
2895 /* Copy the texture content to the staging texture. */
2896 pDevice->pImmediateContext->CopyResource(pBackendSurface->pStagingTexture, pBackendSurface->u.pTexture2D);
2897 }
2898 else if (enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
2899 pMappedTexture = pBackendSurface->pStagingTexture;
2900 else
2901 pMappedTexture = pBackendSurface->pDynamicTexture;
2902
2903 UINT const Subresource = 0; /* Screen target surfaces have only one subresource. */
2904 HRESULT hr = pDevice->pImmediateContext->Map(pMappedTexture, Subresource,
2905 d3d11MapType, /* MapFlags = */ 0, &mappedResource);
2906 if (SUCCEEDED(hr))
2907 {
2908 pMap->enmMapType = enmMapType;
2909 pMap->box = clipBox;
2910 pMap->cbPixel = pSurface->cbBlock;
2911 pMap->cbRowPitch = mappedResource.RowPitch;
2912 pMap->cbDepthPitch = mappedResource.DepthPitch;
2913 pMap->pvData = (uint8_t *)mappedResource.pData
2914 + pMap->box.x * pMap->cbPixel
2915 + pMap->box.y * pMap->cbRowPitch
2916 + pMap->box.z * pMap->cbDepthPitch;
2917 }
2918 else
2919 rc = VERR_NOT_SUPPORTED;
2920 }
2921 else if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE
2922 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_CUBE_TEXTURE
2923 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
2924 {
2925//Assert(pImage->face == 0 && pImage->mipmap == 0);
2926if (!( (pBackendSurface->pStagingTexture && pBackendSurface->pDynamicTexture)
2927 || (pBackendSurface->pStagingTexture3D && pBackendSurface->pDynamicTexture3D)
2928 )
2929 )
2930{
2931 AssertFailed();
2932 return VERR_NOT_IMPLEMENTED;
2933}
2934
2935 dxSurfaceWait(pState, pSurface, pSurface->idAssociatedContext);
2936
2937 ID3D11Resource *pMappedResource;
2938 if (enmMapType == VMSVGA3D_SURFACE_MAP_READ)
2939 {
2940 pMappedResource = (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
2941 ? (ID3D11Resource *)pBackendSurface->pStagingTexture3D
2942 : (ID3D11Resource *)pBackendSurface->pStagingTexture;
2943
2944 /* Copy the texture content to the staging texture.
2945 * The requested miplevel of the texture is copied to the miplevel 0 of the staging texture,
2946 * because the staging (and dynamic) structures do not have miplevels.
2947 * Always copy entire miplevel so all Dst are zero and pSrcBox is NULL, as D3D11 requires.
2948 */
2949 ID3D11Resource *pDstResource = pMappedResource;
2950 UINT DstSubresource = 0;
2951 UINT DstX = 0;
2952 UINT DstY = 0;
2953 UINT DstZ = 0;
2954 ID3D11Resource *pSrcResource = pBackendSurface->u.pResource;
2955 UINT SrcSubresource = D3D11CalcSubresource(pImage->mipmap, pImage->face, pSurface->cLevels);
2956 D3D11_BOX *pSrcBox = NULL;
2957 //D3D11_BOX SrcBox;
2958 //SrcBox.left = 0;
2959 //SrcBox.top = 0;
2960 //SrcBox.front = 0;
2961 //SrcBox.right = pMipLevel->mipmapSize.width;
2962 //SrcBox.bottom = pMipLevel->mipmapSize.height;
2963 //SrcBox.back = pMipLevel->mipmapSize.depth;
2964 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
2965 pSrcResource, SrcSubresource, pSrcBox);
2966 }
2967 else if (enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
2968 pMappedResource = (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
2969 ? (ID3D11Resource *)pBackendSurface->pStagingTexture3D
2970 : (ID3D11Resource *)pBackendSurface->pStagingTexture;
2971 else
2972 pMappedResource = (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
2973 ? (ID3D11Resource *)pBackendSurface->pDynamicTexture3D
2974 : (ID3D11Resource *)pBackendSurface->pDynamicTexture;
2975
2976 UINT const Subresource = 0;
2977 HRESULT hr = pDevice->pImmediateContext->Map(pMappedResource, Subresource,
2978 d3d11MapType, /* MapFlags = */ 0, &mappedResource);
2979 if (SUCCEEDED(hr))
2980 {
2981 pMap->enmMapType = enmMapType;
2982 pMap->box = clipBox;
2983 pMap->cbPixel = pSurface->cbBlock;
2984 pMap->cbRowPitch = mappedResource.RowPitch;
2985 pMap->cbDepthPitch = mappedResource.DepthPitch;
2986 pMap->pvData = (uint8_t *)mappedResource.pData
2987 + pMap->box.x * pMap->cbPixel
2988 + pMap->box.y * pMap->cbRowPitch
2989 + pMap->box.z * pMap->cbDepthPitch;
2990 }
2991 else
2992 rc = VERR_NOT_SUPPORTED;
2993 }
2994 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
2995 {
2996 /* Map the staging buffer. */
2997 rc = dxStagingBufferRealloc(pDevice, pMipLevel->cbSurface);
2998 if (RT_SUCCESS(rc))
2999 {
3000 if (enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3001 {
3002 /* Copy from the buffer to the staging buffer. */
3003 ID3D11Resource *pDstResource = pDevice->pStagingBuffer;
3004 UINT DstSubresource = 0;
3005 UINT DstX = clipBox.x;
3006 UINT DstY = clipBox.y;
3007 UINT DstZ = clipBox.z;
3008 ID3D11Resource *pSrcResource = pBackendSurface->u.pResource;
3009 UINT SrcSubresource = 0;
3010 D3D11_BOX SrcBox;
3011 SrcBox.left = clipBox.x;
3012 SrcBox.top = clipBox.y;
3013 SrcBox.front = clipBox.z;
3014 SrcBox.right = clipBox.w;
3015 SrcBox.bottom = clipBox.h;
3016 SrcBox.back = clipBox.d;
3017 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3018 pSrcResource, SrcSubresource, &SrcBox);
3019 }
3020
3021 UINT const Subresource = 0; /* Buffers have only one subresource. */
3022 HRESULT hr = pDevice->pImmediateContext->Map(pDevice->pStagingBuffer, Subresource,
3023 d3d11MapType, /* MapFlags = */ 0, &mappedResource);
3024 if (SUCCEEDED(hr))
3025 {
3026 pMap->enmMapType = enmMapType;
3027 pMap->box = clipBox;
3028 pMap->cbPixel = pSurface->cbBlock;
3029 pMap->cbRowPitch = mappedResource.RowPitch;
3030 pMap->cbDepthPitch = mappedResource.DepthPitch;
3031 pMap->pvData = (uint8_t *)mappedResource.pData
3032 + pMap->box.x * pMap->cbPixel
3033 + pMap->box.y * pMap->cbRowPitch
3034 + pMap->box.z * pMap->cbDepthPitch;
3035 }
3036 else
3037 rc = VERR_NOT_SUPPORTED;
3038 }
3039 }
3040 else
3041 {
3042 // UINT D3D11CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT MipLevels);
3043 /** @todo Implement. */
3044 AssertFailed();
3045 rc = VERR_NOT_IMPLEMENTED;
3046 }
3047
3048 return rc;
3049}
3050
3051
3052static DECLCALLBACK(int) vmsvga3dBackSurfaceUnmap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, VMSVGA3D_MAPPED_SURFACE *pMap, bool fWritten)
3053{
3054 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3055 AssertReturn(pState, VERR_INVALID_STATE);
3056
3057 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3058 AssertReturn(pBackend, VERR_INVALID_STATE);
3059
3060 PVMSVGA3DSURFACE pSurface;
3061 int rc = vmsvga3dSurfaceFromSid(pState, pImage->sid, &pSurface);
3062 AssertRCReturn(rc, rc);
3063
3064 /* The called should not use the function for system memory surfaces. */
3065 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
3066 AssertReturn(pBackendSurface, VERR_INVALID_PARAMETER);
3067
3068 PVMSVGA3DMIPMAPLEVEL pMipLevel;
3069 rc = vmsvga3dMipmapLevel(pSurface, pImage->face, pImage->mipmap, &pMipLevel);
3070 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
3071
3072 /* A surface is always mapped by the DX context which has created the surface. */
3073 DXDEVICE *pDevice = dxDeviceFromCid(pSurface->idAssociatedContext, pState);
3074 AssertReturn(pDevice && pDevice->pDevice, VERR_INVALID_STATE);
3075
3076 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
3077 {
3078 ID3D11Texture2D *pMappedTexture;
3079 if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3080 pMappedTexture = pBackendSurface->pStagingTexture;
3081 else if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
3082 pMappedTexture = pBackendSurface->pStagingTexture;
3083 else
3084 pMappedTexture = pBackendSurface->pDynamicTexture;
3085
3086 UINT const Subresource = 0; /* Screen target surfaces have only one subresource. */
3087 pDevice->pImmediateContext->Unmap(pMappedTexture, Subresource);
3088
3089 if ( fWritten
3090 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
3091 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
3092 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
3093 {
3094 ID3D11Resource *pDstResource = pBackendSurface->u.pTexture2D;
3095 UINT DstSubresource = Subresource;
3096 UINT DstX = pMap->box.x;
3097 UINT DstY = pMap->box.y;
3098 UINT DstZ = pMap->box.z;
3099 ID3D11Resource *pSrcResource = pMappedTexture;
3100 UINT SrcSubresource = Subresource;
3101 D3D11_BOX SrcBox;
3102 SrcBox.left = pMap->box.x;
3103 SrcBox.top = pMap->box.y;
3104 SrcBox.front = pMap->box.z;
3105 SrcBox.right = pMap->box.x + pMap->box.w;
3106 SrcBox.bottom = pMap->box.y + pMap->box.h;
3107 SrcBox.back = pMap->box.z + pMap->box.d;
3108
3109 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3110 pSrcResource, SrcSubresource, &SrcBox);
3111
3112 pBackendSurface->cidDrawing = pSurface->idAssociatedContext;
3113 }
3114 }
3115 else if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE
3116 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_CUBE_TEXTURE
3117 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3118 {
3119 ID3D11Resource *pMappedResource;
3120 if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3121 pMappedResource = (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3122 ? (ID3D11Resource *)pBackendSurface->pStagingTexture3D
3123 : (ID3D11Resource *)pBackendSurface->pStagingTexture;
3124 else if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
3125 pMappedResource = (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3126 ? (ID3D11Resource *)pBackendSurface->pStagingTexture3D
3127 : (ID3D11Resource *)pBackendSurface->pStagingTexture;
3128 else
3129 pMappedResource = (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3130 ? (ID3D11Resource *)pBackendSurface->pDynamicTexture3D
3131 : (ID3D11Resource *)pBackendSurface->pDynamicTexture;
3132
3133 UINT const Subresource = 0; /* Staging or dynamic textures have one subresource. */
3134 pDevice->pImmediateContext->Unmap(pMappedResource, Subresource);
3135
3136 if ( fWritten
3137 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
3138 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
3139 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
3140 {
3141 /* If entire resource must be copied then use pSrcBox = NULL and dst point (0,0,0)
3142 * Because DX11 insists on this for some resource types, for example DEPTH_STENCIL resources.
3143 */
3144 uint32_t const cWidth0 = pSurface->paMipmapLevels[0].mipmapSize.width;
3145 uint32_t const cHeight0 = pSurface->paMipmapLevels[0].mipmapSize.height;
3146 uint32_t const cDepth0 = pSurface->paMipmapLevels[0].mipmapSize.depth;
3147 bool const fEntireResource = pMap->box.x == 0 && pMap->box.y == 0 && pMap->box.z == 0
3148 && pMap->box.w == cWidth0 && pMap->box.h == cHeight0 && pMap->box.d == cDepth0;
3149
3150 ID3D11Resource *pDstResource = pBackendSurface->u.pResource;
3151 UINT DstSubresource = D3D11CalcSubresource(pImage->mipmap, pImage->face, pSurface->cLevels);
3152 UINT DstX = (pMap->box.x / pSurface->cxBlock) * pSurface->cxBlock;
3153 UINT DstY = (pMap->box.y / pSurface->cyBlock) * pSurface->cyBlock;
3154 UINT DstZ = pMap->box.z;
3155 ID3D11Resource *pSrcResource = pMappedResource;
3156 UINT SrcSubresource = Subresource;
3157 D3D11_BOX *pSrcBox;
3158 D3D11_BOX SrcBox;
3159 if (fEntireResource)
3160 pSrcBox = NULL;
3161 else
3162 {
3163 uint32_t const cxBlocks = (pMap->box.w + pSurface->cxBlock - 1) / pSurface->cxBlock;
3164 uint32_t const cyBlocks = (pMap->box.h + pSurface->cyBlock - 1) / pSurface->cyBlock;
3165
3166 SrcBox.left = DstX;
3167 SrcBox.top = DstY;
3168 SrcBox.front = DstZ;
3169 SrcBox.right = DstX + cxBlocks * pSurface->cxBlock;
3170 SrcBox.bottom = DstY + cyBlocks * pSurface->cyBlock;
3171 SrcBox.back = DstZ + pMap->box.d;
3172 pSrcBox = &SrcBox;
3173 }
3174
3175 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3176 pSrcResource, SrcSubresource, pSrcBox);
3177
3178 pBackendSurface->cidDrawing = pSurface->idAssociatedContext;
3179 }
3180 }
3181 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
3182 {
3183 /* Unmap the staging buffer. */
3184 UINT const Subresource = 0; /* Buffers have only one subresource. */
3185 pDevice->pImmediateContext->Unmap(pDevice->pStagingBuffer, Subresource);
3186
3187 /* Copy from the staging buffer to the actual buffer */
3188 if ( fWritten
3189 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
3190 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
3191 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
3192 {
3193 ID3D11Resource *pDstResource = pBackendSurface->u.pResource;
3194 UINT DstSubresource = 0;
3195 UINT DstX = (pMap->box.x / pSurface->cxBlock) * pSurface->cxBlock;
3196 UINT DstY = (pMap->box.y / pSurface->cyBlock) * pSurface->cyBlock;
3197 UINT DstZ = pMap->box.z;
3198 ID3D11Resource *pSrcResource = pDevice->pStagingBuffer;
3199 UINT SrcSubresource = 0;
3200 D3D11_BOX SrcBox;
3201
3202 uint32_t const cxBlocks = (pMap->box.w + pSurface->cxBlock - 1) / pSurface->cxBlock;
3203 uint32_t const cyBlocks = (pMap->box.h + pSurface->cyBlock - 1) / pSurface->cyBlock;
3204
3205 SrcBox.left = DstX;
3206 SrcBox.top = DstY;
3207 SrcBox.front = DstZ;
3208 SrcBox.right = DstX + cxBlocks * pSurface->cxBlock;
3209 SrcBox.bottom = DstY + cyBlocks * pSurface->cyBlock;
3210 SrcBox.back = DstZ + pMap->box.d;
3211
3212 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3213 pSrcResource, SrcSubresource, &SrcBox);
3214 }
3215 }
3216 else
3217 {
3218 AssertFailed();
3219 rc = VERR_NOT_IMPLEMENTED;
3220 }
3221
3222 return rc;
3223}
3224
3225
3226static DECLCALLBACK(int) vmsvga3dScreenTargetBind(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, uint32_t sid)
3227{
3228 int rc = VINF_SUCCESS;
3229
3230 PVMSVGA3DSURFACE pSurface;
3231 if (sid != SVGA_ID_INVALID)
3232 {
3233 /* Create the surface if does not yet exist. */
3234 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3235 AssertReturn(pState, VERR_INVALID_STATE);
3236
3237 rc = vmsvga3dSurfaceFromSid(pState, sid, &pSurface);
3238 AssertRCReturn(rc, rc);
3239
3240 if (!VMSVGA3DSURFACE_HAS_HW_SURFACE(pSurface))
3241 {
3242 /* Create the actual texture. */
3243 rc = vmsvga3dBackSurfaceCreateScreenTarget(pThisCC, pSurface);
3244 AssertRCReturn(rc, rc);
3245 }
3246 }
3247 else
3248 pSurface = NULL;
3249
3250 /* Notify the HW accelerated screen if it is used. */
3251 VMSVGAHWSCREEN *pHwScreen = pScreen->pHwScreen;
3252 if (!pHwScreen)
3253 return VINF_SUCCESS;
3254
3255 /* Same surface -> do nothing. */
3256 if (pHwScreen->sidScreenTarget == sid)
3257 return VINF_SUCCESS;
3258
3259 if (sid != SVGA_ID_INVALID)
3260 {
3261 AssertReturn( pSurface->pBackendSurface
3262 && pSurface->pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET, VERR_INVALID_PARAMETER);
3263
3264 HANDLE const hSharedSurface = pHwScreen->SharedHandle;
3265 rc = vmsvga3dDrvNotifyBindSurface(pThisCC, pScreen, hSharedSurface);
3266 }
3267
3268 if (RT_SUCCESS(rc))
3269 {
3270 pHwScreen->sidScreenTarget = sid;
3271 }
3272
3273 return rc;
3274}
3275
3276
3277static DECLCALLBACK(int) vmsvga3dScreenTargetUpdate(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, SVGA3dRect const *pRect)
3278{
3279 VMSVGAHWSCREEN *pHwScreen = pScreen->pHwScreen;
3280 AssertReturn(pHwScreen, VERR_NOT_SUPPORTED);
3281
3282 if (pHwScreen->sidScreenTarget == SVGA_ID_INVALID)
3283 return VINF_SUCCESS; /* No surface bound. */
3284
3285 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3286 AssertReturn(pState, VERR_INVALID_STATE);
3287
3288 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3289 AssertReturn(pBackend, VERR_INVALID_STATE);
3290
3291 PVMSVGA3DSURFACE pSurface;
3292 int rc = vmsvga3dSurfaceFromSid(pState, pHwScreen->sidScreenTarget, &pSurface);
3293 AssertRCReturn(rc, rc);
3294
3295 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
3296 AssertReturn(pBackendSurface && pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET, VERR_INVALID_PARAMETER);
3297
3298 SVGA3dRect boundRect;
3299 boundRect.x = 0;
3300 boundRect.y = 0;
3301 boundRect.w = pSurface->paMipmapLevels[0].mipmapSize.width;
3302 boundRect.h = pSurface->paMipmapLevels[0].mipmapSize.height;
3303 SVGA3dRect clipRect = *pRect;
3304 vmsvgaR3Clip3dRect(&boundRect, &clipRect);
3305 ASSERT_GUEST_RETURN(clipRect.w && clipRect.h, VERR_INVALID_PARAMETER);
3306
3307 /* Wait for the surface to finish drawing. */
3308 dxSurfaceWait(pState, pSurface, DX_CID_BACKEND);
3309
3310 /* Copy the screen texture to the shared surface. */
3311 DWORD result = pHwScreen->pDXGIKeyedMutex->AcquireSync(0, 10000);
3312 if (result == WAIT_OBJECT_0)
3313 {
3314 pBackend->device.pImmediateContext->CopyResource(pHwScreen->pTexture, pBackendSurface->u.pTexture2D);
3315
3316 dxDeviceFlush(&pBackend->device);
3317
3318 result = pHwScreen->pDXGIKeyedMutex->ReleaseSync(1);
3319 }
3320 else
3321 AssertFailed();
3322
3323 rc = vmsvga3dDrvNotifyUpdate(pThisCC, pScreen, pRect->x, pRect->y, pRect->w, pRect->h);
3324 return rc;
3325}
3326
3327
3328/*
3329 *
3330 * 3D interface.
3331 *
3332 */
3333
3334static DECLCALLBACK(int) vmsvga3dBackQueryCaps(PVGASTATECC pThisCC, SVGA3dDevCapIndex idx3dCaps, uint32_t *pu32Val)
3335{
3336 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3337 AssertReturn(pState, VERR_INVALID_STATE);
3338
3339 int rc = VINF_SUCCESS;
3340
3341 *pu32Val = 0;
3342
3343 if (idx3dCaps > SVGA3D_DEVCAP_MAX)
3344 {
3345 LogRelMax(16, ("VMSVGA: unsupported SVGA3D_DEVCAP %d\n", idx3dCaps));
3346 return VERR_NOT_SUPPORTED;
3347 }
3348
3349 D3D_FEATURE_LEVEL const FeatureLevel = pState->pBackend->device.FeatureLevel;
3350
3351 /* Most values are taken from:
3352 * https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-intro
3353 *
3354 * Shader values are from
3355 * https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-models
3356 */
3357
3358 switch (idx3dCaps)
3359 {
3360 case SVGA3D_DEVCAP_3D:
3361 *pu32Val = 1;
3362 break;
3363
3364 case SVGA3D_DEVCAP_MAX_LIGHTS:
3365 *pu32Val = SVGA3D_NUM_LIGHTS; /* VGPU9. Not applicable to DX11. */
3366 break;
3367
3368 case SVGA3D_DEVCAP_MAX_TEXTURES:
3369 *pu32Val = SVGA3D_NUM_TEXTURE_UNITS; /* VGPU9. Not applicable to DX11. */
3370 break;
3371
3372 case SVGA3D_DEVCAP_MAX_CLIP_PLANES:
3373 *pu32Val = SVGA3D_NUM_CLIPPLANES;
3374 break;
3375
3376 case SVGA3D_DEVCAP_VERTEX_SHADER_VERSION:
3377 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3378 *pu32Val = SVGA3DVSVERSION_40;
3379 else
3380 *pu32Val = SVGA3DVSVERSION_30;
3381 break;
3382
3383 case SVGA3D_DEVCAP_VERTEX_SHADER:
3384 *pu32Val = 1;
3385 break;
3386
3387 case SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION:
3388 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3389 *pu32Val = SVGA3DPSVERSION_40;
3390 else
3391 *pu32Val = SVGA3DPSVERSION_30;
3392 break;
3393
3394 case SVGA3D_DEVCAP_FRAGMENT_SHADER:
3395 *pu32Val = 1;
3396 break;
3397
3398 case SVGA3D_DEVCAP_MAX_RENDER_TARGETS:
3399 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3400 *pu32Val = 8;
3401 else
3402 *pu32Val = 4;
3403 break;
3404
3405 case SVGA3D_DEVCAP_S23E8_TEXTURES:
3406 case SVGA3D_DEVCAP_S10E5_TEXTURES:
3407 /* Must be obsolete by now; surface format caps specify the same thing. */
3408 break;
3409
3410 case SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND:
3411 /* Obsolete */
3412 break;
3413
3414 /*
3415 * 2. The BUFFER_FORMAT capabilities are deprecated, and they always
3416 * return TRUE. Even on physical hardware that does not support
3417 * these formats natively, the SVGA3D device will provide an emulation
3418 * which should be invisible to the guest OS.
3419 */
3420 case SVGA3D_DEVCAP_D16_BUFFER_FORMAT:
3421 case SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT:
3422 case SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT:
3423 *pu32Val = 1;
3424 break;
3425
3426 case SVGA3D_DEVCAP_QUERY_TYPES:
3427 /* Obsolete */
3428 break;
3429
3430 case SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING:
3431 /* Obsolete */
3432 break;
3433
3434 case SVGA3D_DEVCAP_MAX_POINT_SIZE:
3435 AssertCompile(sizeof(uint32_t) == sizeof(float));
3436 *(float *)pu32Val = 256.0f; /* VGPU9. Not applicable to DX11. */
3437 break;
3438
3439 case SVGA3D_DEVCAP_MAX_SHADER_TEXTURES:
3440 /* Obsolete */
3441 break;
3442
3443 case SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH:
3444 case SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT:
3445 if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
3446 *pu32Val = 16384;
3447 else if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3448 *pu32Val = 8192;
3449 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_3)
3450 *pu32Val = 4096;
3451 else
3452 *pu32Val = 2048;
3453 break;
3454
3455 case SVGA3D_DEVCAP_MAX_VOLUME_EXTENT:
3456 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3457 *pu32Val = 2048;
3458 else
3459 *pu32Val = 256;
3460 break;
3461
3462 case SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT:
3463 if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
3464 *pu32Val = 16384;
3465 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_3)
3466 *pu32Val = 8192;
3467 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
3468 *pu32Val = 2048;
3469 else
3470 *pu32Val = 128;
3471 break;
3472
3473 case SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO:
3474 /* Obsolete */
3475 break;
3476
3477 case SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY:
3478 if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
3479 *pu32Val = D3D11_REQ_MAXANISOTROPY;
3480 else
3481 *pu32Val = 2; // D3D_FL9_1_DEFAULT_MAX_ANISOTROPY;
3482 break;
3483
3484 case SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT:
3485 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3486 *pu32Val = UINT32_MAX;
3487 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
3488 *pu32Val = 1048575; // D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT;
3489 else
3490 *pu32Val = 65535; // D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT;
3491 break;
3492
3493 case SVGA3D_DEVCAP_MAX_VERTEX_INDEX:
3494 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3495 *pu32Val = UINT32_MAX;
3496 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
3497 *pu32Val = 1048575;
3498 else
3499 *pu32Val = 65534;
3500 break;
3501
3502 case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS:
3503 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3504 *pu32Val = UINT32_MAX;
3505 else
3506 *pu32Val = 512;
3507 break;
3508
3509 case SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS:
3510 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3511 *pu32Val = UINT32_MAX;
3512 else
3513 *pu32Val = 512;
3514 break;
3515
3516 case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS:
3517 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3518 *pu32Val = 4096;
3519 else
3520 *pu32Val = 32;
3521 break;
3522
3523 case SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS:
3524 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3525 *pu32Val = 4096;
3526 else
3527 *pu32Val = 32;
3528 break;
3529
3530 case SVGA3D_DEVCAP_TEXTURE_OPS:
3531 /* Obsolete */
3532 break;
3533
3534 case SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8:
3535 case SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8:
3536 case SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10:
3537 case SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5:
3538 case SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5:
3539 case SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4:
3540 case SVGA3D_DEVCAP_SURFACEFMT_R5G6B5:
3541 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16:
3542 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8:
3543 case SVGA3D_DEVCAP_SURFACEFMT_ALPHA8:
3544 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8:
3545 case SVGA3D_DEVCAP_SURFACEFMT_Z_D16:
3546 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8:
3547 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8:
3548 case SVGA3D_DEVCAP_SURFACEFMT_DXT1:
3549 case SVGA3D_DEVCAP_SURFACEFMT_DXT2:
3550 case SVGA3D_DEVCAP_SURFACEFMT_DXT3:
3551 case SVGA3D_DEVCAP_SURFACEFMT_DXT4:
3552 case SVGA3D_DEVCAP_SURFACEFMT_DXT5:
3553 case SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8:
3554 case SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10:
3555 case SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8:
3556 case SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8:
3557 case SVGA3D_DEVCAP_SURFACEFMT_CxV8U8:
3558 case SVGA3D_DEVCAP_SURFACEFMT_R_S10E5:
3559 case SVGA3D_DEVCAP_SURFACEFMT_R_S23E8:
3560 case SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5:
3561 case SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8:
3562 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5:
3563 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8:
3564 case SVGA3D_DEVCAP_SURFACEFMT_V16U16:
3565 case SVGA3D_DEVCAP_SURFACEFMT_G16R16:
3566 case SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16:
3567 case SVGA3D_DEVCAP_SURFACEFMT_UYVY:
3568 case SVGA3D_DEVCAP_SURFACEFMT_YUY2:
3569 case SVGA3D_DEVCAP_SURFACEFMT_NV12:
3570 case SVGA3D_DEVCAP_DEAD10: /* SVGA3D_DEVCAP_SURFACEFMT_AYUV */
3571 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF16:
3572 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF24:
3573 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT:
3574 case SVGA3D_DEVCAP_SURFACEFMT_ATI1:
3575 case SVGA3D_DEVCAP_SURFACEFMT_ATI2:
3576 case SVGA3D_DEVCAP_SURFACEFMT_YV12:
3577 {
3578 SVGA3dSurfaceFormat const enmFormat = vmsvgaDXDevCapSurfaceFmt2Format(idx3dCaps);
3579 rc = vmsvgaDXCheckFormatSupportPreDX(pState, enmFormat, pu32Val);
3580 break;
3581 }
3582
3583 case SVGA3D_DEVCAP_MISSING62:
3584 /* Unused */
3585 break;
3586
3587 case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES:
3588 /* Obsolete */
3589 break;
3590
3591 case SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS:
3592 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3593 *pu32Val = 8;
3594 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_3)
3595 *pu32Val = 4; // D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT
3596 else
3597 *pu32Val = 1; // D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT
3598 break;
3599
3600 case SVGA3D_DEVCAP_DEAD4: /* SVGA3D_DEVCAP_MULTISAMPLE_NONMASKABLESAMPLES */
3601 case SVGA3D_DEVCAP_DEAD5: /* SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES */
3602 *pu32Val = (1 << (2-1)) | (1 << (4-1)) | (1 << (8-1)); /* 2x, 4x, 8x */
3603 break;
3604
3605 case SVGA3D_DEVCAP_DEAD7: /* SVGA3D_DEVCAP_ALPHATOCOVERAGE */
3606 /* Obsolete */
3607 break;
3608
3609 case SVGA3D_DEVCAP_DEAD6: /* SVGA3D_DEVCAP_SUPERSAMPLE */
3610 /* Obsolete */
3611 break;
3612
3613 case SVGA3D_DEVCAP_AUTOGENMIPMAPS:
3614 *pu32Val = 1;
3615 break;
3616
3617 case SVGA3D_DEVCAP_MAX_CONTEXT_IDS:
3618 *pu32Val = SVGA3D_MAX_CONTEXT_IDS;
3619 break;
3620
3621 case SVGA3D_DEVCAP_MAX_SURFACE_IDS:
3622 *pu32Val = SVGA3D_MAX_SURFACE_IDS;
3623 break;
3624
3625 case SVGA3D_DEVCAP_DEAD1:
3626 /* Obsolete */
3627 break;
3628
3629 case SVGA3D_DEVCAP_DEAD8: /* SVGA3D_DEVCAP_VIDEO_DECODE */
3630 /* Obsolete */
3631 break;
3632
3633 case SVGA3D_DEVCAP_DEAD9: /* SVGA3D_DEVCAP_VIDEO_PROCESS */
3634 /* Obsolete */
3635 break;
3636
3637 case SVGA3D_DEVCAP_LINE_AA:
3638 *pu32Val = 1;
3639 break;
3640
3641 case SVGA3D_DEVCAP_LINE_STIPPLE:
3642 *pu32Val = 0; /* DX11 does not seem to support this directly. */
3643 break;
3644
3645 case SVGA3D_DEVCAP_MAX_LINE_WIDTH:
3646 AssertCompile(sizeof(uint32_t) == sizeof(float));
3647 *(float *)pu32Val = 1.0f;
3648 break;
3649
3650 case SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH:
3651 AssertCompile(sizeof(uint32_t) == sizeof(float));
3652 *(float *)pu32Val = 1.0f;
3653 break;
3654
3655 case SVGA3D_DEVCAP_DEAD3: /* Old SVGA3D_DEVCAP_LOGICOPS */
3656 /* Deprecated. */
3657 AssertCompile(SVGA3D_DEVCAP_DEAD3 == 92); /* Newer SVGA headers redefine this. */
3658 break;
3659
3660 case SVGA3D_DEVCAP_TS_COLOR_KEY:
3661 *pu32Val = 0; /* DX11 does not seem to support this directly. */
3662 break;
3663
3664 case SVGA3D_DEVCAP_DEAD2:
3665 break;
3666
3667 case SVGA3D_DEVCAP_DXCONTEXT:
3668 *pu32Val = 1;
3669 break;
3670
3671 case SVGA3D_DEVCAP_DEAD11: /* SVGA3D_DEVCAP_MAX_TEXTURE_ARRAY_SIZE */
3672 *pu32Val = D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
3673 break;
3674
3675 case SVGA3D_DEVCAP_DX_MAX_VERTEXBUFFERS:
3676 *pu32Val = D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT;
3677 break;
3678
3679 case SVGA3D_DEVCAP_DX_MAX_CONSTANT_BUFFERS:
3680 *pu32Val = D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT;
3681 break;
3682
3683 case SVGA3D_DEVCAP_DX_PROVOKING_VERTEX:
3684 *pu32Val = 0; /* boolean */
3685 break;
3686
3687 case SVGA3D_DEVCAP_DXFMT_X8R8G8B8:
3688 case SVGA3D_DEVCAP_DXFMT_A8R8G8B8:
3689 case SVGA3D_DEVCAP_DXFMT_R5G6B5:
3690 case SVGA3D_DEVCAP_DXFMT_X1R5G5B5:
3691 case SVGA3D_DEVCAP_DXFMT_A1R5G5B5:
3692 case SVGA3D_DEVCAP_DXFMT_A4R4G4B4:
3693 case SVGA3D_DEVCAP_DXFMT_Z_D32:
3694 case SVGA3D_DEVCAP_DXFMT_Z_D16:
3695 case SVGA3D_DEVCAP_DXFMT_Z_D24S8:
3696 case SVGA3D_DEVCAP_DXFMT_Z_D15S1:
3697 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8:
3698 case SVGA3D_DEVCAP_DXFMT_LUMINANCE4_ALPHA4:
3699 case SVGA3D_DEVCAP_DXFMT_LUMINANCE16:
3700 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8_ALPHA8:
3701 case SVGA3D_DEVCAP_DXFMT_DXT1:
3702 case SVGA3D_DEVCAP_DXFMT_DXT2:
3703 case SVGA3D_DEVCAP_DXFMT_DXT3:
3704 case SVGA3D_DEVCAP_DXFMT_DXT4:
3705 case SVGA3D_DEVCAP_DXFMT_DXT5:
3706 case SVGA3D_DEVCAP_DXFMT_BUMPU8V8:
3707 case SVGA3D_DEVCAP_DXFMT_BUMPL6V5U5:
3708 case SVGA3D_DEVCAP_DXFMT_BUMPX8L8V8U8:
3709 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD1:
3710 case SVGA3D_DEVCAP_DXFMT_ARGB_S10E5:
3711 case SVGA3D_DEVCAP_DXFMT_ARGB_S23E8:
3712 case SVGA3D_DEVCAP_DXFMT_A2R10G10B10:
3713 case SVGA3D_DEVCAP_DXFMT_V8U8:
3714 case SVGA3D_DEVCAP_DXFMT_Q8W8V8U8:
3715 case SVGA3D_DEVCAP_DXFMT_CxV8U8:
3716 case SVGA3D_DEVCAP_DXFMT_X8L8V8U8:
3717 case SVGA3D_DEVCAP_DXFMT_A2W10V10U10:
3718 case SVGA3D_DEVCAP_DXFMT_ALPHA8:
3719 case SVGA3D_DEVCAP_DXFMT_R_S10E5:
3720 case SVGA3D_DEVCAP_DXFMT_R_S23E8:
3721 case SVGA3D_DEVCAP_DXFMT_RG_S10E5:
3722 case SVGA3D_DEVCAP_DXFMT_RG_S23E8:
3723 case SVGA3D_DEVCAP_DXFMT_BUFFER:
3724 case SVGA3D_DEVCAP_DXFMT_Z_D24X8:
3725 case SVGA3D_DEVCAP_DXFMT_V16U16:
3726 case SVGA3D_DEVCAP_DXFMT_G16R16:
3727 case SVGA3D_DEVCAP_DXFMT_A16B16G16R16:
3728 case SVGA3D_DEVCAP_DXFMT_UYVY:
3729 case SVGA3D_DEVCAP_DXFMT_YUY2:
3730 case SVGA3D_DEVCAP_DXFMT_NV12:
3731 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD2: /* SVGA3D_DEVCAP_DXFMT_AYUV */
3732 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_TYPELESS:
3733 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_UINT:
3734 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_SINT:
3735 case SVGA3D_DEVCAP_DXFMT_R32G32B32_TYPELESS:
3736 case SVGA3D_DEVCAP_DXFMT_R32G32B32_FLOAT:
3737 case SVGA3D_DEVCAP_DXFMT_R32G32B32_UINT:
3738 case SVGA3D_DEVCAP_DXFMT_R32G32B32_SINT:
3739 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_TYPELESS:
3740 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UINT:
3741 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SNORM:
3742 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SINT:
3743 case SVGA3D_DEVCAP_DXFMT_R32G32_TYPELESS:
3744 case SVGA3D_DEVCAP_DXFMT_R32G32_UINT:
3745 case SVGA3D_DEVCAP_DXFMT_R32G32_SINT:
3746 case SVGA3D_DEVCAP_DXFMT_R32G8X24_TYPELESS:
3747 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT_S8X24_UINT:
3748 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT_X8X24:
3749 case SVGA3D_DEVCAP_DXFMT_X32_G8X24_UINT:
3750 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_TYPELESS:
3751 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UINT:
3752 case SVGA3D_DEVCAP_DXFMT_R11G11B10_FLOAT:
3753 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_TYPELESS:
3754 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM:
3755 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM_SRGB:
3756 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UINT:
3757 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SINT:
3758 case SVGA3D_DEVCAP_DXFMT_R16G16_TYPELESS:
3759 case SVGA3D_DEVCAP_DXFMT_R16G16_UINT:
3760 case SVGA3D_DEVCAP_DXFMT_R16G16_SINT:
3761 case SVGA3D_DEVCAP_DXFMT_R32_TYPELESS:
3762 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT:
3763 case SVGA3D_DEVCAP_DXFMT_R32_UINT:
3764 case SVGA3D_DEVCAP_DXFMT_R32_SINT:
3765 case SVGA3D_DEVCAP_DXFMT_R24G8_TYPELESS:
3766 case SVGA3D_DEVCAP_DXFMT_D24_UNORM_S8_UINT:
3767 case SVGA3D_DEVCAP_DXFMT_R24_UNORM_X8:
3768 case SVGA3D_DEVCAP_DXFMT_X24_G8_UINT:
3769 case SVGA3D_DEVCAP_DXFMT_R8G8_TYPELESS:
3770 case SVGA3D_DEVCAP_DXFMT_R8G8_UNORM:
3771 case SVGA3D_DEVCAP_DXFMT_R8G8_UINT:
3772 case SVGA3D_DEVCAP_DXFMT_R8G8_SINT:
3773 case SVGA3D_DEVCAP_DXFMT_R16_TYPELESS:
3774 case SVGA3D_DEVCAP_DXFMT_R16_UNORM:
3775 case SVGA3D_DEVCAP_DXFMT_R16_UINT:
3776 case SVGA3D_DEVCAP_DXFMT_R16_SNORM:
3777 case SVGA3D_DEVCAP_DXFMT_R16_SINT:
3778 case SVGA3D_DEVCAP_DXFMT_R8_TYPELESS:
3779 case SVGA3D_DEVCAP_DXFMT_R8_UNORM:
3780 case SVGA3D_DEVCAP_DXFMT_R8_UINT:
3781 case SVGA3D_DEVCAP_DXFMT_R8_SNORM:
3782 case SVGA3D_DEVCAP_DXFMT_R8_SINT:
3783 case SVGA3D_DEVCAP_DXFMT_P8:
3784 case SVGA3D_DEVCAP_DXFMT_R9G9B9E5_SHAREDEXP:
3785 case SVGA3D_DEVCAP_DXFMT_R8G8_B8G8_UNORM:
3786 case SVGA3D_DEVCAP_DXFMT_G8R8_G8B8_UNORM:
3787 case SVGA3D_DEVCAP_DXFMT_BC1_TYPELESS:
3788 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM_SRGB:
3789 case SVGA3D_DEVCAP_DXFMT_BC2_TYPELESS:
3790 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM_SRGB:
3791 case SVGA3D_DEVCAP_DXFMT_BC3_TYPELESS:
3792 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM_SRGB:
3793 case SVGA3D_DEVCAP_DXFMT_BC4_TYPELESS:
3794 case SVGA3D_DEVCAP_DXFMT_ATI1:
3795 case SVGA3D_DEVCAP_DXFMT_BC4_SNORM:
3796 case SVGA3D_DEVCAP_DXFMT_BC5_TYPELESS:
3797 case SVGA3D_DEVCAP_DXFMT_ATI2:
3798 case SVGA3D_DEVCAP_DXFMT_BC5_SNORM:
3799 case SVGA3D_DEVCAP_DXFMT_R10G10B10_XR_BIAS_A2_UNORM:
3800 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_TYPELESS:
3801 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM_SRGB:
3802 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_TYPELESS:
3803 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM_SRGB:
3804 case SVGA3D_DEVCAP_DXFMT_Z_DF16:
3805 case SVGA3D_DEVCAP_DXFMT_Z_DF24:
3806 case SVGA3D_DEVCAP_DXFMT_Z_D24S8_INT:
3807 case SVGA3D_DEVCAP_DXFMT_YV12:
3808 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_FLOAT:
3809 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_FLOAT:
3810 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UNORM:
3811 case SVGA3D_DEVCAP_DXFMT_R32G32_FLOAT:
3812 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UNORM:
3813 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SNORM:
3814 case SVGA3D_DEVCAP_DXFMT_R16G16_FLOAT:
3815 case SVGA3D_DEVCAP_DXFMT_R16G16_UNORM:
3816 case SVGA3D_DEVCAP_DXFMT_R16G16_SNORM:
3817 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT:
3818 case SVGA3D_DEVCAP_DXFMT_R8G8_SNORM:
3819 case SVGA3D_DEVCAP_DXFMT_R16_FLOAT:
3820 case SVGA3D_DEVCAP_DXFMT_D16_UNORM:
3821 case SVGA3D_DEVCAP_DXFMT_A8_UNORM:
3822 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM:
3823 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM:
3824 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM:
3825 case SVGA3D_DEVCAP_DXFMT_B5G6R5_UNORM:
3826 case SVGA3D_DEVCAP_DXFMT_B5G5R5A1_UNORM:
3827 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM:
3828 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM:
3829 case SVGA3D_DEVCAP_DXFMT_BC4_UNORM:
3830 case SVGA3D_DEVCAP_DXFMT_BC5_UNORM:
3831 case SVGA3D_DEVCAP_DXFMT_BC6H_TYPELESS:
3832 case SVGA3D_DEVCAP_DXFMT_BC6H_UF16:
3833 case SVGA3D_DEVCAP_DXFMT_BC6H_SF16:
3834 case SVGA3D_DEVCAP_DXFMT_BC7_TYPELESS:
3835 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM:
3836 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM_SRGB:
3837 {
3838 SVGA3dSurfaceFormat const enmFormat = vmsvgaDXDevCapDxfmt2Format(idx3dCaps);
3839 rc = vmsvgaDXCheckFormatSupport(pState, enmFormat, pu32Val);
3840 break;
3841 }
3842
3843 case SVGA3D_DEVCAP_SM41:
3844 *pu32Val = 0; /* boolean */
3845 break;
3846
3847 case SVGA3D_DEVCAP_MULTISAMPLE_2X:
3848 *pu32Val = 0; /* boolean */
3849 break;
3850
3851 case SVGA3D_DEVCAP_MULTISAMPLE_4X:
3852 *pu32Val = 0; /* boolean */
3853 break;
3854
3855 case SVGA3D_DEVCAP_MS_FULL_QUALITY:
3856 *pu32Val = 0; /* boolean */
3857 break;
3858
3859 case SVGA3D_DEVCAP_LOGICOPS:
3860 AssertCompile(SVGA3D_DEVCAP_LOGICOPS == 248);
3861 *pu32Val = 0; /* boolean */
3862 break;
3863
3864 case SVGA3D_DEVCAP_LOGIC_BLENDOPS:
3865 *pu32Val = 0; /* boolean */
3866 break;
3867
3868 case SVGA3D_DEVCAP_RESERVED_1:
3869 break;
3870
3871 case SVGA3D_DEVCAP_RESERVED_2:
3872 break;
3873
3874 case SVGA3D_DEVCAP_SM5:
3875 *pu32Val = 0; /* boolean */
3876 break;
3877
3878 case SVGA3D_DEVCAP_MULTISAMPLE_8X:
3879 *pu32Val = 0; /* boolean */
3880 break;
3881
3882 case SVGA3D_DEVCAP_MAX:
3883 case SVGA3D_DEVCAP_INVALID:
3884 rc = VERR_NOT_SUPPORTED;
3885 break;
3886 }
3887
3888 return rc;
3889}
3890
3891
3892static DECLCALLBACK(int) vmsvga3dBackChangeMode(PVGASTATECC pThisCC)
3893{
3894 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3895 AssertReturn(pState, VERR_INVALID_STATE);
3896
3897 return VINF_SUCCESS;
3898}
3899
3900
3901static DECLCALLBACK(int) vmsvga3dBackSurfaceCopy(PVGASTATECC pThisCC, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src,
3902 uint32_t cCopyBoxes, SVGA3dCopyBox *pBox)
3903{
3904 RT_NOREF(cCopyBoxes, pBox);
3905
3906 LogFunc(("src sid %d -> dst sid %d\n", src.sid, dest.sid));
3907
3908 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3909 AssertReturn(pState, VERR_INVALID_STATE);
3910
3911 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3912
3913 PVMSVGA3DSURFACE pSrcSurface;
3914 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, src.sid, &pSrcSurface);
3915 AssertRCReturn(rc, rc);
3916
3917 PVMSVGA3DSURFACE pDstSurface;
3918 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, dest.sid, &pDstSurface);
3919 AssertRCReturn(rc, rc);
3920
3921 LogFunc(("src%s cid %d -> dst%s cid %d\n",
3922 pSrcSurface->pBackendSurface ? "" : " sysmem",
3923 pSrcSurface ? pSrcSurface->idAssociatedContext : SVGA_ID_INVALID,
3924 pDstSurface->pBackendSurface ? "" : " sysmem",
3925 pDstSurface ? pDstSurface->idAssociatedContext : SVGA_ID_INVALID));
3926
3927 //DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
3928 //AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
3929
3930 if (pSrcSurface->pBackendSurface)
3931 {
3932 if (pDstSurface->pBackendSurface == NULL)
3933 {
3934 /* Create the target if it can be used as a device context shared resource (render or screen target). */
3935 if (dxIsSurfaceShareable(pDstSurface))
3936 {
3937 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, NULL, pDstSurface);
3938 AssertRCReturn(rc, rc);
3939 }
3940 }
3941
3942 if (pDstSurface->pBackendSurface)
3943 {
3944 /* Surface -> Surface. */
3945 /* Expect both of them to be shared surfaces created by the backend context. */
3946 Assert(pSrcSurface->idAssociatedContext == DX_CID_BACKEND && pDstSurface->idAssociatedContext == DX_CID_BACKEND);
3947
3948 /* Wait for the source surface to finish drawing. */
3949 dxSurfaceWait(pState, pSrcSurface, DX_CID_BACKEND);
3950
3951 DXDEVICE *pDXDevice = &pBackend->device;
3952
3953 /* Clip the box. */
3954 PVMSVGA3DMIPMAPLEVEL pSrcMipLevel;
3955 rc = vmsvga3dMipmapLevel(pSrcSurface, src.face, src.mipmap, &pSrcMipLevel);
3956 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
3957
3958 PVMSVGA3DMIPMAPLEVEL pDstMipLevel;
3959 rc = vmsvga3dMipmapLevel(pDstSurface, dest.face, dest.mipmap, &pDstMipLevel);
3960 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
3961
3962 SVGA3dCopyBox clipBox = *pBox;
3963 vmsvgaR3ClipCopyBox(&pSrcMipLevel->mipmapSize, &pDstMipLevel->mipmapSize, &clipBox);
3964
3965 UINT DstSubresource = vmsvga3dCalcSubresource(dest.mipmap, dest.face, pDstSurface->cLevels);
3966 UINT DstX = clipBox.x;
3967 UINT DstY = clipBox.y;
3968 UINT DstZ = clipBox.z;
3969
3970 UINT SrcSubresource = vmsvga3dCalcSubresource(src.mipmap, src.face, pSrcSurface->cLevels);
3971 D3D11_BOX SrcBox;
3972 SrcBox.left = clipBox.srcx;
3973 SrcBox.top = clipBox.srcy;
3974 SrcBox.front = clipBox.srcz;
3975 SrcBox.right = clipBox.srcx + clipBox.w;
3976 SrcBox.bottom = clipBox.srcy + clipBox.h;
3977 SrcBox.back = clipBox.srcz + clipBox.d;
3978
3979 Assert(cCopyBoxes == 1); /** @todo */
3980
3981 ID3D11Resource *pDstResource;
3982 ID3D11Resource *pSrcResource;
3983 pDstResource = dxResource(pState, pDstSurface, NULL);
3984 pSrcResource = dxResource(pState, pSrcSurface, NULL);
3985
3986 pDXDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3987 pSrcResource, SrcSubresource, &SrcBox);
3988
3989 pDstSurface->pBackendSurface->cidDrawing = DX_CID_BACKEND;
3990 }
3991 else
3992 {
3993 /* Surface -> Memory. */
3994 AssertFailed(); /** @todo implement */
3995 }
3996 }
3997 else
3998 {
3999 /* Memory -> Surface. */
4000 AssertFailed(); /** @todo implement */
4001 }
4002
4003 return rc;
4004}
4005
4006
4007static DECLCALLBACK(void) vmsvga3dBackUpdateHostScreenViewport(PVGASTATECC pThisCC, uint32_t idScreen, VMSVGAVIEWPORT const *pOldViewport)
4008{
4009 RT_NOREF(pThisCC, idScreen, pOldViewport);
4010 /** @todo Scroll the screen content without requiring the guest to redraw. */
4011}
4012
4013
4014static DECLCALLBACK(int) vmsvga3dBackSurfaceUpdateHeapBuffers(PVGASTATECC pThisCC, PVMSVGA3DSURFACE pSurface)
4015{
4016 /** @todo */
4017 RT_NOREF(pThisCC, pSurface);
4018 return VERR_NOT_IMPLEMENTED;
4019}
4020
4021
4022/**
4023 * Create a new 3d context
4024 *
4025 * @returns VBox status code.
4026 * @param pThisCC The VGA/VMSVGA state for ring-3.
4027 * @param cid Context id
4028 */
4029static DECLCALLBACK(int) vmsvga3dBackContextDefine(PVGASTATECC pThisCC, uint32_t cid)
4030{
4031 RT_NOREF(cid);
4032
4033 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4034 AssertReturn(pState, VERR_INVALID_STATE);
4035
4036 AssertFailed();
4037 return VERR_NOT_IMPLEMENTED;
4038}
4039
4040
4041/**
4042 * Destroy an existing 3d context
4043 *
4044 * @returns VBox status code.
4045 * @param pThisCC The VGA/VMSVGA state for ring-3.
4046 * @param cid Context id
4047 */
4048static DECLCALLBACK(int) vmsvga3dBackContextDestroy(PVGASTATECC pThisCC, uint32_t cid)
4049{
4050 RT_NOREF(cid);
4051
4052 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4053 AssertReturn(pState, VERR_INVALID_STATE);
4054
4055 AssertFailed();
4056 return VINF_SUCCESS;
4057}
4058
4059
4060static DECLCALLBACK(int) vmsvga3dBackSetTransform(PVGASTATECC pThisCC, uint32_t cid, SVGA3dTransformType type, float matrix[16])
4061{
4062 RT_NOREF(cid, type, matrix);
4063
4064 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4065 AssertReturn(pState, VERR_INVALID_STATE);
4066
4067 AssertFailed();
4068 return VINF_SUCCESS;
4069}
4070
4071
4072static DECLCALLBACK(int) vmsvga3dBackSetZRange(PVGASTATECC pThisCC, uint32_t cid, SVGA3dZRange zRange)
4073{
4074 RT_NOREF(cid, zRange);
4075
4076 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4077 AssertReturn(pState, VERR_INVALID_STATE);
4078
4079 AssertFailed();
4080 return VINF_SUCCESS;
4081}
4082
4083
4084static DECLCALLBACK(int) vmsvga3dBackSetRenderState(PVGASTATECC pThisCC, uint32_t cid, uint32_t cRenderStates, SVGA3dRenderState *pRenderState)
4085{
4086 RT_NOREF(cid, cRenderStates, pRenderState);
4087
4088 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4089 AssertReturn(pState, VERR_INVALID_STATE);
4090
4091 AssertFailed();
4092 return VINF_SUCCESS;
4093}
4094
4095
4096static DECLCALLBACK(int) vmsvga3dBackSetRenderTarget(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRenderTargetType type, SVGA3dSurfaceImageId target)
4097{
4098 RT_NOREF(cid, type, target);
4099
4100 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4101 AssertReturn(pState, VERR_INVALID_STATE);
4102
4103 AssertFailed();
4104 return VINF_SUCCESS;
4105}
4106
4107
4108static DECLCALLBACK(int) vmsvga3dBackSetTextureState(PVGASTATECC pThisCC, uint32_t cid, uint32_t cTextureStates, SVGA3dTextureState *pTextureState)
4109{
4110 RT_NOREF(cid, cTextureStates, pTextureState);
4111
4112 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4113 AssertReturn(pState, VERR_INVALID_STATE);
4114
4115 AssertFailed();
4116 return VINF_SUCCESS;
4117}
4118
4119
4120static DECLCALLBACK(int) vmsvga3dBackSetMaterial(PVGASTATECC pThisCC, uint32_t cid, SVGA3dFace face, SVGA3dMaterial *pMaterial)
4121{
4122 RT_NOREF(cid, face, pMaterial);
4123
4124 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4125 AssertReturn(pState, VERR_INVALID_STATE);
4126
4127 AssertFailed();
4128 return VINF_SUCCESS;
4129}
4130
4131
4132static DECLCALLBACK(int) vmsvga3dBackSetLightData(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, SVGA3dLightData *pData)
4133{
4134 RT_NOREF(cid, index, pData);
4135
4136 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4137 AssertReturn(pState, VERR_INVALID_STATE);
4138
4139 AssertFailed();
4140 return VINF_SUCCESS;
4141}
4142
4143
4144static DECLCALLBACK(int) vmsvga3dBackSetLightEnabled(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, uint32_t enabled)
4145{
4146 RT_NOREF(cid, index, enabled);
4147
4148 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4149 AssertReturn(pState, VERR_INVALID_STATE);
4150
4151 AssertFailed();
4152 return VINF_SUCCESS;
4153}
4154
4155
4156static DECLCALLBACK(int) vmsvga3dBackSetViewPort(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRect *pRect)
4157{
4158 RT_NOREF(cid, pRect);
4159
4160 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4161 AssertReturn(pState, VERR_INVALID_STATE);
4162
4163 AssertFailed();
4164 return VINF_SUCCESS;
4165}
4166
4167
4168static DECLCALLBACK(int) vmsvga3dBackSetClipPlane(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, float plane[4])
4169{
4170 RT_NOREF(cid, index, plane);
4171
4172 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4173 AssertReturn(pState, VERR_INVALID_STATE);
4174
4175 AssertFailed();
4176 return VINF_SUCCESS;
4177}
4178
4179
4180static DECLCALLBACK(int) vmsvga3dBackCommandClear(PVGASTATECC pThisCC, uint32_t cid, SVGA3dClearFlag clearFlag, uint32_t color, float depth,
4181 uint32_t stencil, uint32_t cRects, SVGA3dRect *pRect)
4182{
4183 /* From SVGA3D_BeginClear comments:
4184 *
4185 * Clear is not affected by clipping, depth test, or other
4186 * render state which affects the fragment pipeline.
4187 *
4188 * Therefore this code must ignore the current scissor rect.
4189 */
4190
4191 RT_NOREF(cid, clearFlag, color, depth, stencil, cRects, pRect);
4192
4193 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4194 AssertReturn(pState, VERR_INVALID_STATE);
4195
4196 AssertFailed();
4197 return VINF_SUCCESS;
4198}
4199
4200
4201static DECLCALLBACK(int) vmsvga3dBackDrawPrimitives(PVGASTATECC pThisCC, uint32_t cid, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl,
4202 uint32_t numRanges, SVGA3dPrimitiveRange *pRange,
4203 uint32_t cVertexDivisor, SVGA3dVertexDivisor *pVertexDivisor)
4204{
4205 RT_NOREF(cid, numVertexDecls, pVertexDecl, numRanges, pRange, cVertexDivisor, pVertexDivisor);
4206
4207 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4208 AssertReturn(pState, VERR_INVALID_STATE);
4209
4210 AssertFailed();
4211 return VINF_SUCCESS;
4212}
4213
4214
4215static DECLCALLBACK(int) vmsvga3dBackSetScissorRect(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRect *pRect)
4216{
4217 RT_NOREF(cid, pRect);
4218
4219 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4220 AssertReturn(pState, VERR_INVALID_STATE);
4221
4222 AssertFailed();
4223 return VINF_SUCCESS;
4224}
4225
4226
4227static DECLCALLBACK(int) vmsvga3dBackGenerateMipmaps(PVGASTATECC pThisCC, uint32_t sid, SVGA3dTextureFilter filter)
4228{
4229 RT_NOREF(sid, filter);
4230
4231 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4232 AssertReturn(pState, VERR_INVALID_STATE);
4233
4234 AssertFailed();
4235 return VINF_SUCCESS;
4236}
4237
4238
4239static DECLCALLBACK(int) vmsvga3dBackShaderDefine(PVGASTATECC pThisCC, uint32_t cid, uint32_t shid, SVGA3dShaderType type,
4240 uint32_t cbData, uint32_t *pShaderData)
4241{
4242 RT_NOREF(cid, shid, type, cbData, pShaderData);
4243
4244 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4245 AssertReturn(pState, VERR_INVALID_STATE);
4246
4247 AssertFailed();
4248 return VINF_SUCCESS;
4249}
4250
4251
4252static DECLCALLBACK(int) vmsvga3dBackShaderDestroy(PVGASTATECC pThisCC, uint32_t cid, uint32_t shid, SVGA3dShaderType type)
4253{
4254 RT_NOREF(cid, shid, type);
4255
4256 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4257 AssertReturn(pState, VERR_INVALID_STATE);
4258
4259 AssertFailed();
4260 return VINF_SUCCESS;
4261}
4262
4263
4264static DECLCALLBACK(int) vmsvga3dBackShaderSet(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext, uint32_t cid, SVGA3dShaderType type, uint32_t shid)
4265{
4266 RT_NOREF(pContext, cid, type, shid);
4267
4268 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4269 AssertReturn(pState, VERR_INVALID_STATE);
4270
4271 AssertFailed();
4272 return VINF_SUCCESS;
4273}
4274
4275
4276static DECLCALLBACK(int) vmsvga3dBackShaderSetConst(PVGASTATECC pThisCC, uint32_t cid, uint32_t reg, SVGA3dShaderType type,
4277 SVGA3dShaderConstType ctype, uint32_t cRegisters, uint32_t *pValues)
4278{
4279 RT_NOREF(cid, reg, type, ctype, cRegisters, pValues);
4280
4281 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4282 AssertReturn(pState, VERR_INVALID_STATE);
4283
4284 AssertFailed();
4285 return VINF_SUCCESS;
4286}
4287
4288
4289/**
4290 * Destroy backend specific surface bits (part of SVGA_3D_CMD_SURFACE_DESTROY).
4291 *
4292 * @param pThisCC The device context.
4293 * @param pSurface The surface being destroyed.
4294 */
4295static DECLCALLBACK(void) vmsvga3dBackSurfaceDestroy(PVGASTATECC pThisCC, PVMSVGA3DSURFACE pSurface)
4296{
4297 RT_NOREF(pThisCC);
4298
4299 /* The caller should not use the function for system memory surfaces. */
4300 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
4301 if (!pBackendSurface)
4302 return;
4303 pSurface->pBackendSurface = NULL;
4304
4305 LogFunc(("sid=%u\n", pSurface->id));
4306
4307 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
4308 {
4309 D3D_RELEASE(pBackendSurface->pStagingTexture);
4310 D3D_RELEASE(pBackendSurface->pDynamicTexture);
4311 D3D_RELEASE(pBackendSurface->u.pTexture2D);
4312 }
4313 else if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE
4314 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_CUBE_TEXTURE)
4315 {
4316 D3D_RELEASE(pBackendSurface->pStagingTexture);
4317 D3D_RELEASE(pBackendSurface->pDynamicTexture);
4318 D3D_RELEASE(pBackendSurface->u.pTexture2D);
4319 }
4320 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
4321 {
4322 D3D_RELEASE(pBackendSurface->pStagingTexture3D);
4323 D3D_RELEASE(pBackendSurface->pDynamicTexture3D);
4324 D3D_RELEASE(pBackendSurface->u.pTexture3D);
4325 }
4326 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
4327 {
4328 D3D_RELEASE(pBackendSurface->u.pBuffer);
4329 }
4330 else
4331 {
4332 AssertFailed();
4333 }
4334
4335 RTMemFree(pBackendSurface);
4336
4337 /* No context has created the surface, because the surface does not exist anymore. */
4338 pSurface->idAssociatedContext = SVGA_ID_INVALID;
4339}
4340
4341
4342/**
4343 * Backend worker for implementing SVGA_3D_CMD_SURFACE_STRETCHBLT.
4344 *
4345 * @returns VBox status code.
4346 * @param pThis The VGA device instance.
4347 * @param pState The VMSVGA3d state.
4348 * @param pDstSurface The destination host surface.
4349 * @param uDstFace The destination face (valid).
4350 * @param uDstMipmap The destination mipmap level (valid).
4351 * @param pDstBox The destination box.
4352 * @param pSrcSurface The source host surface.
4353 * @param uSrcFace The destination face (valid).
4354 * @param uSrcMipmap The source mimap level (valid).
4355 * @param pSrcBox The source box.
4356 * @param enmMode The strecht blt mode .
4357 * @param pContext The VMSVGA3d context (already current for OGL).
4358 */
4359static DECLCALLBACK(int) vmsvga3dBackSurfaceStretchBlt(PVGASTATE pThis, PVMSVGA3DSTATE pState,
4360 PVMSVGA3DSURFACE pDstSurface, uint32_t uDstFace, uint32_t uDstMipmap, SVGA3dBox const *pDstBox,
4361 PVMSVGA3DSURFACE pSrcSurface, uint32_t uSrcFace, uint32_t uSrcMipmap, SVGA3dBox const *pSrcBox,
4362 SVGA3dStretchBltMode enmMode, PVMSVGA3DCONTEXT pContext)
4363{
4364 RT_NOREF(pThis, pState, pDstSurface, uDstFace, uDstMipmap, pDstBox,
4365 pSrcSurface, uSrcFace, uSrcMipmap, pSrcBox, enmMode, pContext);
4366
4367 AssertFailed();
4368 return VINF_SUCCESS;
4369}
4370
4371
4372/**
4373 * Backend worker for implementing SVGA_3D_CMD_SURFACE_DMA that copies one box.
4374 *
4375 * @returns Failure status code or @a rc.
4376 * @param pThis The shared VGA/VMSVGA instance data.
4377 * @param pThisCC The VGA/VMSVGA state for ring-3.
4378 * @param pState The VMSVGA3d state.
4379 * @param pSurface The host surface.
4380 * @param pMipLevel Mipmap level. The caller knows it already.
4381 * @param uHostFace The host face (valid).
4382 * @param uHostMipmap The host mipmap level (valid).
4383 * @param GuestPtr The guest pointer.
4384 * @param cbGuestPitch The guest pitch.
4385 * @param transfer The transfer direction.
4386 * @param pBox The box to copy (clipped, valid, except for guest's srcx, srcy, srcz).
4387 * @param pContext The context (for OpenGL).
4388 * @param rc The current rc for all boxes.
4389 * @param iBox The current box number (for Direct 3D).
4390 */
4391static DECLCALLBACK(int) vmsvga3dBackSurfaceDMACopyBox(PVGASTATE pThis, PVGASTATECC pThisCC, PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface,
4392 PVMSVGA3DMIPMAPLEVEL pMipLevel, uint32_t uHostFace, uint32_t uHostMipmap,
4393 SVGAGuestPtr GuestPtr, uint32_t cbGuestPitch, SVGA3dTransferType transfer,
4394 SVGA3dCopyBox const *pBox, PVMSVGA3DCONTEXT pContext, int rc, int iBox)
4395{
4396 RT_NOREF(pState, pMipLevel, pContext, iBox);
4397
4398 /* The called should not use the function for system memory surfaces. */
4399 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
4400 AssertReturn(pBackendSurface, VERR_INVALID_PARAMETER);
4401
4402 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
4403 {
4404 /** @todo This is generic code and should be in DevVGA-SVGA3d.cpp for backends which support Map/Unmap. */
4405 AssertReturn(uHostFace == 0 && uHostMipmap == 0, VERR_INVALID_PARAMETER);
4406
4407 uint32_t const u32GuestBlockX = pBox->srcx / pSurface->cxBlock;
4408 uint32_t const u32GuestBlockY = pBox->srcy / pSurface->cyBlock;
4409 Assert(u32GuestBlockX * pSurface->cxBlock == pBox->srcx);
4410 Assert(u32GuestBlockY * pSurface->cyBlock == pBox->srcy);
4411 uint32_t const cBlocksX = (pBox->w + pSurface->cxBlock - 1) / pSurface->cxBlock;
4412 uint32_t const cBlocksY = (pBox->h + pSurface->cyBlock - 1) / pSurface->cyBlock;
4413 AssertMsgReturn(cBlocksX && cBlocksY, ("Empty box %dx%d\n", pBox->w, pBox->h), VERR_INTERNAL_ERROR);
4414
4415 /* vmsvgaR3GmrTransfer verifies uGuestOffset.
4416 * srcx(u32GuestBlockX) and srcy(u32GuestBlockY) have been verified in vmsvga3dSurfaceDMA
4417 * to not cause 32 bit overflow when multiplied by cbBlock and cbGuestPitch.
4418 */
4419 uint64_t const uGuestOffset = u32GuestBlockX * pSurface->cbBlock + u32GuestBlockY * cbGuestPitch;
4420 AssertReturn(uGuestOffset < UINT32_MAX, VERR_INVALID_PARAMETER);
4421
4422 SVGA3dSurfaceImageId image;
4423 image.sid = pSurface->id;
4424 image.face = uHostFace;
4425 image.mipmap = uHostMipmap;
4426
4427 SVGA3dBox box;
4428 box.x = pBox->x;
4429 box.y = pBox->y;
4430 box.z = 0;
4431 box.w = pBox->w;
4432 box.h = pBox->h;
4433 box.d = 1;
4434
4435 VMSVGA3D_SURFACE_MAP const enmMap = transfer == SVGA3D_WRITE_HOST_VRAM
4436 ? VMSVGA3D_SURFACE_MAP_WRITE
4437 : VMSVGA3D_SURFACE_MAP_READ;
4438
4439 VMSVGA3D_MAPPED_SURFACE map;
4440 rc = vmsvga3dBackSurfaceMap(pThisCC, &image, &box, enmMap, &map);
4441 if (RT_SUCCESS(rc))
4442 {
4443 /* Prepare parameters for vmsvgaR3GmrTransfer, which needs the host buffer address, size
4444 * and offset of the first scanline.
4445 */
4446 uint32_t const cbLockedBuf = map.cbRowPitch * cBlocksY;
4447 uint8_t *pu8LockedBuf = (uint8_t *)map.pvData;
4448 uint32_t const offLockedBuf = 0;
4449
4450 rc = vmsvgaR3GmrTransfer(pThis,
4451 pThisCC,
4452 transfer,
4453 pu8LockedBuf,
4454 cbLockedBuf,
4455 offLockedBuf,
4456 map.cbRowPitch,
4457 GuestPtr,
4458 (uint32_t)uGuestOffset,
4459 cbGuestPitch,
4460 cBlocksX * pSurface->cbBlock,
4461 cBlocksY);
4462 AssertRC(rc);
4463
4464 // Log4(("first line:\n%.*Rhxd\n", cBlocksX * pSurface->cbBlock, LockedRect.pBits));
4465
4466 //vmsvga3dMapWriteBmpFile(&map, "Dynamic");
4467
4468 vmsvga3dBackSurfaceUnmap(pThisCC, &image, &map, /* fWritten = */ true);
4469 }
4470#if 0
4471 //DEBUG_BREAKPOINT_TEST();
4472 rc = vmsvga3dBackSurfaceMap(pThisCC, &image, NULL, VMSVGA3D_SURFACE_MAP_READ, &map);
4473 if (RT_SUCCESS(rc))
4474 {
4475 vmsvga3dMapWriteBmpFile(&map, "Staging");
4476
4477 vmsvga3dBackSurfaceUnmap(pThisCC, &image, &map, /* fWritten = */ false);
4478 }
4479#endif
4480 }
4481 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE)
4482 {
4483 /** @todo This is generic code and should be in DevVGA-SVGA3d.cpp for backends which support Map/Unmap. */
4484 AssertReturn(uHostFace == 0 && uHostMipmap == 0, VERR_INVALID_PARAMETER);
4485
4486 uint32_t const u32GuestBlockX = pBox->srcx / pSurface->cxBlock;
4487 uint32_t const u32GuestBlockY = pBox->srcy / pSurface->cyBlock;
4488 Assert(u32GuestBlockX * pSurface->cxBlock == pBox->srcx);
4489 Assert(u32GuestBlockY * pSurface->cyBlock == pBox->srcy);
4490 uint32_t const cBlocksX = (pBox->w + pSurface->cxBlock - 1) / pSurface->cxBlock;
4491 uint32_t const cBlocksY = (pBox->h + pSurface->cyBlock - 1) / pSurface->cyBlock;
4492 AssertMsgReturn(cBlocksX && cBlocksY, ("Empty box %dx%d\n", pBox->w, pBox->h), VERR_INTERNAL_ERROR);
4493
4494 /* vmsvgaR3GmrTransfer verifies uGuestOffset.
4495 * srcx(u32GuestBlockX) and srcy(u32GuestBlockY) have been verified in vmsvga3dSurfaceDMA
4496 * to not cause 32 bit overflow when multiplied by cbBlock and cbGuestPitch.
4497 */
4498 uint64_t const uGuestOffset = u32GuestBlockX * pSurface->cbBlock + u32GuestBlockY * cbGuestPitch;
4499 AssertReturn(uGuestOffset < UINT32_MAX, VERR_INVALID_PARAMETER);
4500
4501 SVGA3dSurfaceImageId image;
4502 image.sid = pSurface->id;
4503 image.face = uHostFace;
4504 image.mipmap = uHostMipmap;
4505
4506 SVGA3dBox box;
4507 box.x = pBox->x;
4508 box.y = pBox->y;
4509 box.z = 0;
4510 box.w = pBox->w;
4511 box.h = pBox->h;
4512 box.d = 1;
4513
4514 VMSVGA3D_SURFACE_MAP const enmMap = transfer == SVGA3D_WRITE_HOST_VRAM
4515 ? VMSVGA3D_SURFACE_MAP_WRITE
4516 : VMSVGA3D_SURFACE_MAP_READ;
4517
4518 VMSVGA3D_MAPPED_SURFACE map;
4519 rc = vmsvga3dBackSurfaceMap(pThisCC, &image, &box, enmMap, &map);
4520 if (RT_SUCCESS(rc))
4521 {
4522#if 0
4523 if (box.w == 250 && box.h == 250 && box.d == 1 && enmMap == VMSVGA3D_SURFACE_MAP_READ)
4524 {
4525 DEBUG_BREAKPOINT_TEST();
4526 vmsvga3dMapWriteBmpFile(&map, "P");
4527 }
4528#endif
4529 /* Prepare parameters for vmsvgaR3GmrTransfer, which needs the host buffer address, size
4530 * and offset of the first scanline.
4531 */
4532 uint32_t const cbLockedBuf = map.cbRowPitch * cBlocksY;
4533 uint8_t *pu8LockedBuf = (uint8_t *)map.pvData;
4534 uint32_t const offLockedBuf = 0;
4535
4536 rc = vmsvgaR3GmrTransfer(pThis,
4537 pThisCC,
4538 transfer,
4539 pu8LockedBuf,
4540 cbLockedBuf,
4541 offLockedBuf,
4542 map.cbRowPitch,
4543 GuestPtr,
4544 (uint32_t)uGuestOffset,
4545 cbGuestPitch,
4546 cBlocksX * pSurface->cbBlock,
4547 cBlocksY);
4548 AssertRC(rc);
4549
4550 bool const fWritten = (transfer == SVGA3D_WRITE_HOST_VRAM);
4551 vmsvga3dBackSurfaceUnmap(pThisCC, &image, &map, fWritten);
4552 }
4553 }
4554 else
4555 {
4556 AssertMsgFailed(("Unsupported surface type %d\n", pBackendSurface->enmResType));
4557 rc = VERR_NOT_IMPLEMENTED;
4558 }
4559
4560 return rc;
4561}
4562
4563
4564/**
4565 * Create D3D/OpenGL texture object for the specified surface.
4566 *
4567 * Surfaces are created when needed.
4568 *
4569 * @param pThisCC The device context.
4570 * @param pContext The context.
4571 * @param idAssociatedContext Probably the same as pContext->id.
4572 * @param pSurface The surface to create the texture for.
4573 */
4574static DECLCALLBACK(int) vmsvga3dBackCreateTexture(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext,
4575 PVMSVGA3DSURFACE pSurface)
4576
4577{
4578 RT_NOREF(pThisCC, pContext, idAssociatedContext, pSurface);
4579
4580 AssertFailed();
4581 return VINF_SUCCESS;
4582}
4583
4584
4585static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryCreate(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
4586{
4587 RT_NOREF(pThisCC, pContext);
4588 AssertFailed();
4589 return VINF_SUCCESS;
4590}
4591
4592
4593static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryBegin(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
4594{
4595 RT_NOREF(pThisCC, pContext);
4596 AssertFailed();
4597 return VINF_SUCCESS;
4598}
4599
4600
4601static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryEnd(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
4602{
4603 RT_NOREF(pThisCC, pContext);
4604 AssertFailed();
4605 return VINF_SUCCESS;
4606}
4607
4608
4609static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryGetData(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext, uint32_t *pu32Pixels)
4610{
4611 RT_NOREF(pThisCC, pContext);
4612 *pu32Pixels = 0;
4613 AssertFailed();
4614 return VINF_SUCCESS;
4615}
4616
4617
4618static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryDelete(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
4619{
4620 RT_NOREF(pThisCC, pContext);
4621 AssertFailed();
4622 return VINF_SUCCESS;
4623}
4624
4625
4626/*
4627 * DX callbacks.
4628 */
4629
4630static DECLCALLBACK(int) vmsvga3dBackDXDefineContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
4631{
4632 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
4633
4634 /* Allocate a backend specific context structure. */
4635 PVMSVGA3DBACKENDDXCONTEXT pBackendDXContext = (PVMSVGA3DBACKENDDXCONTEXT)RTMemAllocZ(sizeof(VMSVGA3DBACKENDDXCONTEXT));
4636 AssertPtrReturn(pBackendDXContext, VERR_NO_MEMORY);
4637 pDXContext->pBackendDXContext = pBackendDXContext;
4638
4639 LogFunc(("cid %d\n", pDXContext->cid));
4640
4641 int rc = dxDeviceCreate(pBackend, &pBackendDXContext->device);
4642 return rc;
4643}
4644
4645
4646static DECLCALLBACK(int) vmsvga3dBackDXDestroyContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
4647{
4648 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
4649
4650 LogFunc(("cid %d\n", pDXContext->cid));
4651
4652 if (pDXContext->pBackendDXContext)
4653 {
4654 /* Clean up context resources. */
4655 VMSVGA3DBACKENDDXCONTEXT *pBackendDXContext = pDXContext->pBackendDXContext;
4656
4657 if (pBackendDXContext->papRenderTargetView)
4658 DX_RELEASE_ARRAY(pBackendDXContext->cRenderTargetView, pBackendDXContext->papRenderTargetView);
4659 if (pBackendDXContext->papDepthStencilView)
4660 DX_RELEASE_ARRAY(pBackendDXContext->cDepthStencilView, pBackendDXContext->papDepthStencilView);
4661 if (pBackendDXContext->papShaderResourceView)
4662 DX_RELEASE_ARRAY(pBackendDXContext->cShaderResourceView, pBackendDXContext->papShaderResourceView);
4663 if (pBackendDXContext->paElementLayout)
4664 {
4665 for (uint32_t i = 0; i < pBackendDXContext->cElementLayout; ++i)
4666 D3D_RELEASE(pBackendDXContext->paElementLayout[i].pElementLayout);
4667 }
4668 if (pBackendDXContext->papBlendState)
4669 DX_RELEASE_ARRAY(pBackendDXContext->cBlendState, pBackendDXContext->papBlendState);
4670 if (pBackendDXContext->papDepthStencilState)
4671 DX_RELEASE_ARRAY(pBackendDXContext->cDepthStencilState, pBackendDXContext->papDepthStencilState);
4672 if (pBackendDXContext->papRasterizerState)
4673 DX_RELEASE_ARRAY(pBackendDXContext->cRasterizerState, pBackendDXContext->papRasterizerState);
4674 if (pBackendDXContext->papSamplerState)
4675 DX_RELEASE_ARRAY(pBackendDXContext->cSamplerState, pBackendDXContext->papSamplerState);
4676 if (pBackendDXContext->papQuery)
4677 DX_RELEASE_ARRAY(pBackendDXContext->cQuery, pBackendDXContext->papQuery);
4678 if (pBackendDXContext->paShader)
4679 {
4680 for (uint32_t i = 0; i < pBackendDXContext->cShader; ++i)
4681 D3D_RELEASE(pBackendDXContext->paShader[i].pShader); /// @todo dxDestroyShader
4682 }
4683 if (pBackendDXContext->paStreamOutput)
4684 {
4685 for (uint32_t i = 0; i < pBackendDXContext->cStreamOutput; ++i)
4686 dxDestroyStreamOutput(&pBackendDXContext->paStreamOutput[i]);
4687 }
4688
4689 RTMemFreeZ(pBackendDXContext->papBlendState, sizeof(pBackendDXContext->papBlendState[0]) * pBackendDXContext->cBlendState);
4690 RTMemFreeZ(pBackendDXContext->papDepthStencilState, sizeof(pBackendDXContext->papDepthStencilState[0]) * pBackendDXContext->cDepthStencilState);
4691 RTMemFreeZ(pBackendDXContext->papSamplerState, sizeof(pBackendDXContext->papSamplerState[0]) * pBackendDXContext->cSamplerState);
4692 RTMemFreeZ(pBackendDXContext->papRasterizerState, sizeof(pBackendDXContext->papRasterizerState[0]) * pBackendDXContext->cRasterizerState);
4693 RTMemFreeZ(pBackendDXContext->paElementLayout, sizeof(pBackendDXContext->paElementLayout[0]) * pBackendDXContext->cElementLayout);
4694 RTMemFreeZ(pBackendDXContext->papRenderTargetView, sizeof(pBackendDXContext->papRenderTargetView[0]) * pBackendDXContext->cRenderTargetView);
4695 RTMemFreeZ(pBackendDXContext->papDepthStencilView, sizeof(pBackendDXContext->papDepthStencilView[0]) * pBackendDXContext->cDepthStencilView);
4696 RTMemFreeZ(pBackendDXContext->papShaderResourceView, sizeof(pBackendDXContext->papShaderResourceView[0]) * pBackendDXContext->cShaderResourceView);
4697 RTMemFreeZ(pBackendDXContext->papQuery, sizeof(pBackendDXContext->papQuery[0]) * pBackendDXContext->cQuery);
4698 RTMemFreeZ(pBackendDXContext->paShader, sizeof(pBackendDXContext->paShader[0]) * pBackendDXContext->cShader);
4699 RTMemFreeZ(pBackendDXContext->paStreamOutput, sizeof(pBackendDXContext->paStreamOutput[0]) * pBackendDXContext->cStreamOutput);
4700
4701 /* Destroy backend surfaces which belong to this context. */
4702 /** @todo The context should have a list of surfaces (and also shared resources). */
4703 for (uint32_t sid = 0; sid < pThisCC->svga.p3dState->cSurfaces; ++sid)
4704 {
4705 PVMSVGA3DSURFACE const pSurface = pThisCC->svga.p3dState->papSurfaces[sid];
4706 if ( pSurface
4707 && pSurface->id == sid)
4708 {
4709 if (pSurface->idAssociatedContext == pDXContext->cid)
4710 {
4711 Assert(pSurface->pBackendSurface);
4712 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
4713 }
4714 else if (pSurface->idAssociatedContext == DX_CID_BACKEND)
4715 {
4716 /* May have shared resources in this context. */
4717 Assert(pSurface->pBackendSurface);
4718 DXSHAREDTEXTURE *pSharedTexture = (DXSHAREDTEXTURE *)RTAvlU32Get(&pSurface->pBackendSurface->SharedTextureTree, pDXContext->cid);
4719 if (pSharedTexture)
4720 {
4721 Assert(pSharedTexture->sid == sid);
4722 RTAvlU32Remove(&pSurface->pBackendSurface->SharedTextureTree, pDXContext->cid);
4723 D3D_RELEASE(pSharedTexture->pTexture);
4724 RTMemFreeZ(pSharedTexture, sizeof(*pSharedTexture));
4725 }
4726 }
4727 }
4728 }
4729
4730 dxDeviceDestroy(pBackend, &pBackendDXContext->device);
4731
4732 RTMemFreeZ(pBackendDXContext, sizeof(*pBackendDXContext));
4733 pDXContext->pBackendDXContext = NULL;
4734 }
4735 return VINF_SUCCESS;
4736}
4737
4738
4739static DECLCALLBACK(int) vmsvga3dBackDXBindContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
4740{
4741 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
4742 RT_NOREF(pBackend, pDXContext);
4743 return VINF_SUCCESS;
4744}
4745
4746
4747static DECLCALLBACK(int) vmsvga3dBackDXReadbackContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
4748{
4749 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
4750 RT_NOREF(pBackend, pDXContext);
4751 return VINF_SUCCESS;
4752}
4753
4754
4755static DECLCALLBACK(int) vmsvga3dBackDXInvalidateContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
4756{
4757 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
4758
4759 RT_NOREF(pBackend, pDXContext);
4760 AssertFailed(); /** @todo Implement */
4761 return VERR_NOT_IMPLEMENTED;
4762}
4763
4764
4765static DECLCALLBACK(int) vmsvga3dBackDXSetSingleConstantBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t slot, SVGA3dShaderType type, SVGA3dSurfaceId sid, uint32_t offsetInBytes, uint32_t sizeInBytes)
4766{
4767 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
4768 RT_NOREF(pBackend);
4769
4770 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
4771 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
4772
4773 if (sid == SVGA_ID_INVALID)
4774 {
4775 dxConstantBufferSet(pDevice, slot, type, NULL);
4776 return VINF_SUCCESS;
4777 }
4778
4779 PVMSVGA3DSURFACE pSurface;
4780 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
4781 AssertRCReturn(rc, rc);
4782
4783 PVMSVGA3DMIPMAPLEVEL pMipLevel;
4784 rc = vmsvga3dMipmapLevel(pSurface, 0, 0, &pMipLevel);
4785 AssertRCReturn(rc, rc);
4786
4787 uint32_t const cbSurface = pMipLevel->cbSurface;
4788 ASSERT_GUEST_RETURN( offsetInBytes < cbSurface
4789 && sizeInBytes <= cbSurface - offsetInBytes, VERR_INVALID_PARAMETER);
4790
4791 /* Constant buffers are created on demand. */
4792 Assert(pSurface->pBackendSurface == NULL);
4793
4794 /* Upload the current data, if any. */
4795 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
4796 D3D11_SUBRESOURCE_DATA initialData;
4797 if (pMipLevel->pSurfaceData)
4798 {
4799 initialData.pSysMem = (uint8_t *)pMipLevel->pSurfaceData + offsetInBytes;
4800 initialData.SysMemPitch = sizeInBytes;
4801 initialData.SysMemSlicePitch = sizeInBytes;
4802
4803 pInitialData = &initialData;
4804 }
4805
4806 D3D11_BUFFER_DESC bd;
4807 RT_ZERO(bd);
4808 bd.ByteWidth = sizeInBytes;
4809 bd.Usage = D3D11_USAGE_DEFAULT;
4810 bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
4811 bd.CPUAccessFlags = 0;
4812 bd.MiscFlags = 0;
4813 bd.StructureByteStride = 0;
4814
4815 ID3D11Buffer *pBuffer = 0;
4816 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBuffer);
4817 if (SUCCEEDED(hr))
4818 {
4819 dxConstantBufferSet(pDevice, slot, type, pBuffer);
4820 D3D_RELEASE(pBuffer);
4821 }
4822
4823 return VINF_SUCCESS;
4824}
4825
4826
4827static DECLCALLBACK(int) vmsvga3dBackDXSetShaderResources(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t startView, SVGA3dShaderType type, uint32_t cShaderResourceViewId, SVGA3dShaderResourceViewId const *paShaderResourceViewId)
4828{
4829 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
4830 RT_NOREF(pBackend);
4831
4832 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
4833 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
4834
4835 uint32_t const idxShaderState = type - SVGA3D_SHADERTYPE_MIN;
4836 ID3D11ShaderResourceView *papShaderResourceView[SVGA3D_DX_MAX_SRVIEWS];
4837 for (uint32_t i = 0; i < cShaderResourceViewId; ++i)
4838 {
4839 SVGA3dShaderResourceViewId shaderResourceViewId = paShaderResourceViewId[i];
4840 if (shaderResourceViewId != SVGA3D_INVALID_ID)
4841 {
4842 ASSERT_GUEST_RETURN(shaderResourceViewId < pDXContext->pBackendDXContext->cShaderResourceView, VERR_INVALID_PARAMETER);
4843 papShaderResourceView[i] = pDXContext->pBackendDXContext->papShaderResourceView[shaderResourceViewId];
4844 }
4845 else
4846 papShaderResourceView[i] = NULL;
4847
4848 pDXContext->svgaDXContext.shaderState[idxShaderState].shaderResources[startView + i] = shaderResourceViewId;
4849 }
4850
4851 dxShaderResourceViewSet(pDevice, type, startView, cShaderResourceViewId, papShaderResourceView);
4852 return VINF_SUCCESS;
4853}
4854
4855
4856static DECLCALLBACK(int) vmsvga3dBackDXSetShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderType type, PVMSVGA3DSHADER pShader)
4857{
4858 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
4859 RT_NOREF(pBackend);
4860
4861 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
4862 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
4863
4864 DXSHADER *pDXShader;
4865 if (pShader)
4866 {
4867 pDXShader = &pDXContext->pBackendDXContext->paShader[pShader->id];
4868 Assert(pDXShader->pShader);
4869 Assert(pDXShader->enmShaderType >= SVGA3D_SHADERTYPE_MIN && pDXShader->enmShaderType < SVGA3D_SHADERTYPE_MAX);
4870 uint32_t const idxShaderState = pDXShader->enmShaderType - SVGA3D_SHADERTYPE_MIN;
4871 pDXContext->svgaDXContext.shaderState[idxShaderState].shaderId = pShader->id;
4872 }
4873 else
4874 pDXShader = NULL;
4875
4876 dxShaderSet(pDXContext, type, pDXShader);
4877 return VINF_SUCCESS;
4878}
4879
4880
4881static DECLCALLBACK(int) vmsvga3dBackDXSetSamplers(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t startSampler, SVGA3dShaderType type, uint32_t cSamplerId, SVGA3dSamplerId const *paSamplerId)
4882{
4883 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
4884 RT_NOREF(pBackend);
4885
4886 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
4887 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
4888
4889 uint32_t const idxShaderState = type - SVGA3D_SHADERTYPE_MIN;
4890 ID3D11SamplerState *papSamplerState[SVGA3D_DX_MAX_SAMPLERS];
4891 for (uint32_t i = 0; i < cSamplerId; ++i)
4892 {
4893 SVGA3dSamplerId samplerId = paSamplerId[i];
4894 if (samplerId != SVGA3D_INVALID_ID)
4895 {
4896 ASSERT_GUEST_RETURN(samplerId < pDXContext->pBackendDXContext->cSamplerState, VERR_INVALID_PARAMETER);
4897 papSamplerState[i] = pDXContext->pBackendDXContext->papSamplerState[samplerId];
4898 }
4899 else
4900 papSamplerState[i] = NULL;
4901
4902 pDXContext->svgaDXContext.shaderState[idxShaderState].samplers[startSampler + i] = samplerId;
4903 }
4904
4905 dxSamplerSet(pDevice, type, startSampler, cSamplerId, papSamplerState);
4906 return VINF_SUCCESS;
4907}
4908
4909
4910static void dxSetupPipeline(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
4911{
4912 /* Make sure that any draw operations on shader resource views have finished. */
4913 AssertCompile(RT_ELEMENTS(pDXContext->svgaDXContext.shaderState) == SVGA3D_NUM_SHADERTYPE);
4914 AssertCompile(RT_ELEMENTS(pDXContext->svgaDXContext.shaderState[0].shaderResources) == SVGA3D_DX_MAX_SRVIEWS);
4915
4916 for (uint32_t idxShaderState = 0; idxShaderState < SVGA3D_NUM_SHADERTYPE; ++idxShaderState)
4917 {
4918 for (uint32_t idxSR = 0; idxSR < SVGA3D_NUM_SHADERTYPE; ++idxSR)
4919 {
4920 SVGA3dShaderResourceViewId const shaderResourceViewId = pDXContext->svgaDXContext.shaderState[idxShaderState].shaderResources[idxSR];
4921 if (shaderResourceViewId != SVGA3D_INVALID_ID)
4922 {
4923 ASSERT_GUEST_RETURN_VOID(shaderResourceViewId < pDXContext->pBackendDXContext->cShaderResourceView);
4924
4925 uint32_t const sid = dxGetShaderResourceViewSid(pDXContext, shaderResourceViewId);
4926
4927 PVMSVGA3DSURFACE pSurface;
4928 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
4929 AssertRCReturnVoid(rc);
4930
4931 /** @todo The guest might have invalidated the surface. */
4932 AssertContinue(pSurface->pBackendSurface);
4933
4934 /* Wait for the surface to finish drawing. */
4935 dxSurfaceWait(pThisCC->svga.p3dState, pSurface, pDXContext->cid);
4936 }
4937 }
4938 }
4939
4940#ifdef DX_DEFERRED_SET_RENDER_TARGETS
4941 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
4942 AssertReturnVoid(pDevice->pDevice);
4943
4944 pDevice->pImmediateContext->OMSetRenderTargets(pDXContext->pBackendDXContext->state.cRenderTargetViews,
4945 pDXContext->pBackendDXContext->state.papRenderTargetViews,
4946 pDXContext->pBackendDXContext->state.pDepthStencilView);
4947#endif
4948}
4949
4950
4951static DECLCALLBACK(int) vmsvga3dBackDXDraw(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t vertexCount, uint32_t startVertexLocation)
4952{
4953 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
4954 RT_NOREF(pBackend);
4955
4956 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
4957 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
4958
4959 dxSetupPipeline(pThisCC, pDXContext);
4960
4961 if (pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN)
4962 pDevice->pImmediateContext->Draw(vertexCount, startVertexLocation);
4963 else
4964 {
4965 /*
4966 * Emulate SVGA3D_PRIMITIVE_TRIANGLEFAN using an indexed draw of a triangle list.
4967 */
4968
4969 /* Make sure that 16 bit indices are enough. 20000 ~= 65536 / 3 */
4970 AssertReturn(vertexCount <= 20000, VERR_NOT_SUPPORTED);
4971
4972 /* Generate indices. */
4973 UINT const IndexCount = 3 * (vertexCount - 2); /* 3_per_triangle * num_triangles */
4974 UINT const cbAlloc = IndexCount * sizeof(USHORT);
4975 USHORT *paIndices = (USHORT *)RTMemAlloc(cbAlloc);
4976 AssertReturn(paIndices, VERR_NO_MEMORY);
4977 USHORT iVertex = 1;
4978 for (UINT i = 0; i < IndexCount; i+= 3)
4979 {
4980 paIndices[i] = 0;
4981 paIndices[i + 1] = iVertex;
4982 ++iVertex;
4983 paIndices[i + 2] = iVertex;
4984 }
4985
4986 D3D11_SUBRESOURCE_DATA InitData;
4987 InitData.pSysMem = paIndices;
4988 InitData.SysMemPitch = cbAlloc;
4989 InitData.SysMemSlicePitch = cbAlloc;
4990
4991 D3D11_BUFFER_DESC bd;
4992 RT_ZERO(bd);
4993 bd.ByteWidth = cbAlloc;
4994 bd.Usage = D3D11_USAGE_IMMUTABLE;
4995 bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
4996 //bd.CPUAccessFlags = 0;
4997 //bd.MiscFlags = 0;
4998 //bd.StructureByteStride = 0;
4999
5000 ID3D11Buffer *pIndexBuffer = 0;
5001 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, &InitData, &pIndexBuffer);
5002 Assert(SUCCEEDED(hr));RT_NOREF(hr);
5003
5004 /* Save the current index buffer. */
5005 ID3D11Buffer *pSavedIndexBuffer = 0;
5006 DXGI_FORMAT SavedFormat = DXGI_FORMAT_UNKNOWN;
5007 UINT SavedOffset = 0;
5008 pDevice->pImmediateContext->IAGetIndexBuffer(&pSavedIndexBuffer, &SavedFormat, &SavedOffset);
5009
5010 /* Set up the device state. */
5011 pDevice->pImmediateContext->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
5012 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5013
5014 UINT const StartIndexLocation = 0;
5015 INT const BaseVertexLocation = startVertexLocation;
5016 pDevice->pImmediateContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation);
5017
5018 /* Restore the device state. */
5019 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
5020 pDevice->pImmediateContext->IASetIndexBuffer(pSavedIndexBuffer, SavedFormat, SavedOffset);
5021 D3D_RELEASE(pSavedIndexBuffer);
5022
5023 /* Cleanup. */
5024 D3D_RELEASE(pIndexBuffer);
5025 RTMemFree(paIndices);
5026 }
5027
5028 /* Note which surfaces are being drawn. */
5029 dxTrackRenderTargets(pThisCC, pDXContext);
5030
5031 return VINF_SUCCESS;
5032}
5033
5034static int dxReadBuffer(DXDEVICE *pDevice, ID3D11Buffer *pBuffer, UINT Offset, UINT Bytes, void **ppvData, uint32_t *pcbData)
5035{
5036 D3D11_BUFFER_DESC desc;
5037 RT_ZERO(desc);
5038 pBuffer->GetDesc(&desc);
5039
5040 AssertReturn( Offset < desc.ByteWidth
5041 && Bytes <= desc.ByteWidth - Offset, VERR_INVALID_STATE);
5042
5043 void *pvData = RTMemAlloc(Bytes);
5044 if (!pvData)
5045 return VERR_NO_MEMORY;
5046
5047 int rc = dxStagingBufferRealloc(pDevice, Bytes);
5048 if (RT_SUCCESS(rc))
5049 {
5050 /* Copy from the buffer to the staging buffer. */
5051 ID3D11Resource *pDstResource = pDevice->pStagingBuffer;
5052 UINT DstSubresource = 0;
5053 UINT DstX = Offset;
5054 UINT DstY = 0;
5055 UINT DstZ = 0;
5056 ID3D11Resource *pSrcResource = pBuffer;
5057 UINT SrcSubresource = 0;
5058 D3D11_BOX SrcBox;
5059 SrcBox.left = 0;
5060 SrcBox.top = 0;
5061 SrcBox.front = 0;
5062 SrcBox.right = Bytes;
5063 SrcBox.bottom = 1;
5064 SrcBox.back = 1;
5065 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
5066 pSrcResource, SrcSubresource, &SrcBox);
5067
5068 D3D11_MAPPED_SUBRESOURCE mappedResource;
5069 UINT const Subresource = 0; /* Buffers have only one subresource. */
5070 HRESULT hr = pDevice->pImmediateContext->Map(pDevice->pStagingBuffer, Subresource,
5071 D3D11_MAP_READ, /* MapFlags = */ 0, &mappedResource);
5072 if (SUCCEEDED(hr))
5073 {
5074 memcpy(pvData, mappedResource.pData, Bytes);
5075
5076 /* Unmap the staging buffer. */
5077 pDevice->pImmediateContext->Unmap(pDevice->pStagingBuffer, Subresource);
5078 }
5079 else
5080 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
5081
5082 }
5083
5084 if (RT_SUCCESS(rc))
5085 {
5086 *ppvData = pvData;
5087 *pcbData = Bytes;
5088 }
5089 else
5090 {
5091 RTMemFree(*ppvData);
5092 *ppvData = NULL;
5093 *pcbData = 0;
5094 }
5095
5096 return rc;
5097}
5098
5099
5100static int dxDrawIndexedTriangleFan(DXDEVICE *pDevice, uint32_t IndexCountTF, uint32_t StartIndexLocationTF, int32_t BaseVertexLocationTF)
5101{
5102 /*
5103 * Emulate an indexed SVGA3D_PRIMITIVE_TRIANGLEFAN using an indexed draw of triangle list.
5104 */
5105
5106 /* Make sure that 16 bit indices are enough. 20000 ~= 65536 / 3 */
5107 AssertReturn(IndexCountTF <= 20000, VERR_NOT_SUPPORTED);
5108
5109 /* Save the current index buffer. */
5110 ID3D11Buffer *pSavedIndexBuffer = 0;
5111 DXGI_FORMAT SavedFormat = DXGI_FORMAT_UNKNOWN;
5112 UINT SavedOffset = 0;
5113 pDevice->pImmediateContext->IAGetIndexBuffer(&pSavedIndexBuffer, &SavedFormat, &SavedOffset);
5114
5115 AssertReturn( SavedFormat == DXGI_FORMAT_R16_UINT
5116 || SavedFormat == DXGI_FORMAT_R32_UINT, VERR_NOT_SUPPORTED);
5117
5118 /* How many bytes are used by triangle fan indices. */
5119 UINT const BytesPerIndexTF = SavedFormat == DXGI_FORMAT_R16_UINT ? 2 : 4;
5120 UINT const BytesTF = BytesPerIndexTF * IndexCountTF;
5121
5122 /* Read the current index buffer content to obtain indices. */
5123 void *pvDataTF;
5124 uint32_t cbDataTF;
5125 int rc = dxReadBuffer(pDevice, pSavedIndexBuffer, StartIndexLocationTF, BytesTF, &pvDataTF, &cbDataTF);
5126 AssertRCReturn(rc, rc);
5127 AssertReturnStmt(cbDataTF >= BytesPerIndexTF, RTMemFree(pvDataTF), VERR_INVALID_STATE);
5128
5129 /* Generate indices for triangle list. */
5130 UINT const IndexCount = 3 * (IndexCountTF - 2); /* 3_per_triangle * num_triangles */
5131 UINT const cbAlloc = IndexCount * sizeof(USHORT);
5132 USHORT *paIndices = (USHORT *)RTMemAlloc(cbAlloc);
5133 AssertReturnStmt(paIndices, RTMemFree(pvDataTF), VERR_NO_MEMORY);
5134
5135 USHORT iVertex = 1;
5136 if (BytesPerIndexTF == 2)
5137 {
5138 USHORT *paIndicesTF = (USHORT *)pvDataTF;
5139 for (UINT i = 0; i < IndexCount; i+= 3)
5140 {
5141 paIndices[i] = paIndicesTF[0];
5142 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5143 paIndices[i + 1] = paIndicesTF[iVertex];
5144 ++iVertex;
5145 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5146 paIndices[i + 2] = paIndicesTF[iVertex];
5147 }
5148 }
5149 else
5150 {
5151 UINT *paIndicesTF = (UINT *)pvDataTF;
5152 for (UINT i = 0; i < IndexCount; i+= 3)
5153 {
5154 paIndices[i] = paIndicesTF[0];
5155 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5156 paIndices[i + 1] = paIndicesTF[iVertex];
5157 ++iVertex;
5158 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5159 paIndices[i + 2] = paIndicesTF[iVertex];
5160 }
5161 }
5162
5163 D3D11_SUBRESOURCE_DATA InitData;
5164 InitData.pSysMem = paIndices;
5165 InitData.SysMemPitch = cbAlloc;
5166 InitData.SysMemSlicePitch = cbAlloc;
5167
5168 D3D11_BUFFER_DESC bd;
5169 RT_ZERO(bd);
5170 bd.ByteWidth = cbAlloc;
5171 bd.Usage = D3D11_USAGE_IMMUTABLE;
5172 bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
5173 //bd.CPUAccessFlags = 0;
5174 //bd.MiscFlags = 0;
5175 //bd.StructureByteStride = 0;
5176
5177 ID3D11Buffer *pIndexBuffer = 0;
5178 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, &InitData, &pIndexBuffer);
5179 Assert(SUCCEEDED(hr));RT_NOREF(hr);
5180
5181 /* Set up the device state. */
5182 pDevice->pImmediateContext->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
5183 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5184
5185 UINT const StartIndexLocation = 0;
5186 INT const BaseVertexLocation = BaseVertexLocationTF;
5187 pDevice->pImmediateContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation);
5188
5189 /* Restore the device state. */
5190 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
5191 pDevice->pImmediateContext->IASetIndexBuffer(pSavedIndexBuffer, SavedFormat, SavedOffset);
5192 D3D_RELEASE(pSavedIndexBuffer);
5193
5194 /* Cleanup. */
5195 D3D_RELEASE(pIndexBuffer);
5196 RTMemFree(paIndices);
5197 RTMemFree(pvDataTF);
5198
5199 return VINF_SUCCESS;
5200}
5201
5202
5203static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexed(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t indexCount, uint32_t startIndexLocation, int32_t baseVertexLocation)
5204{
5205 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5206 RT_NOREF(pBackend);
5207
5208 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5209 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5210
5211 dxSetupPipeline(pThisCC, pDXContext);
5212
5213 if (pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN)
5214 pDevice->pImmediateContext->DrawIndexed(indexCount, startIndexLocation, baseVertexLocation);
5215 else
5216 {
5217 dxDrawIndexedTriangleFan(pDevice, indexCount, startIndexLocation, baseVertexLocation);
5218 }
5219
5220 /* Note which surfaces are being drawn. */
5221 dxTrackRenderTargets(pThisCC, pDXContext);
5222
5223 return VINF_SUCCESS;
5224}
5225
5226
5227static DECLCALLBACK(int) vmsvga3dBackDXDrawInstanced(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
5228 uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation)
5229{
5230 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5231 RT_NOREF(pBackend);
5232
5233 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5234 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5235
5236 dxSetupPipeline(pThisCC, pDXContext);
5237
5238 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
5239
5240 pDevice->pImmediateContext->DrawInstanced(vertexCountPerInstance, instanceCount, startVertexLocation, startInstanceLocation);
5241
5242 /* Note which surfaces are being drawn. */
5243 dxTrackRenderTargets(pThisCC, pDXContext);
5244
5245 return VINF_SUCCESS;
5246}
5247
5248
5249static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexedInstanced(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
5250 uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation)
5251{
5252 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5253 RT_NOREF(pBackend);
5254
5255 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5256 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5257
5258 dxSetupPipeline(pThisCC, pDXContext);
5259
5260 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
5261
5262 pDevice->pImmediateContext->DrawIndexedInstanced(indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation);
5263
5264 /* Note which surfaces are being drawn. */
5265 dxTrackRenderTargets(pThisCC, pDXContext);
5266
5267 return VINF_SUCCESS;
5268}
5269
5270
5271static DECLCALLBACK(int) vmsvga3dBackDXDrawAuto(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5272{
5273 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
5274 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5275
5276 dxSetupPipeline(pThisCC, pDXContext);
5277
5278 RT_NOREF(pBackend, pDXContext);
5279 AssertFailed(); /** @todo Implement */
5280 return VERR_NOT_IMPLEMENTED;
5281}
5282
5283
5284static DECLCALLBACK(int) vmsvga3dBackDXSetInputLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId)
5285{
5286 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5287 RT_NOREF(pBackend);
5288
5289 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5290 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5291
5292 pDXContext->svgaDXContext.inputAssembly.layoutId = elementLayoutId;
5293
5294 DXELEMENTLAYOUT *pDXElementLayout = &pDXContext->pBackendDXContext->paElementLayout[elementLayoutId];
5295 if (!pDXElementLayout->pElementLayout)
5296 {
5297 uint32_t const idxShaderState = SVGA3D_SHADERTYPE_VS - SVGA3D_SHADERTYPE_MIN;
5298 uint32_t const shid = pDXContext->svgaDXContext.shaderState[idxShaderState].shaderId;
5299 AssertReturnStmt(shid < pDXContext->pBackendDXContext->cShader,
5300 LogRelMax(16, ("VMSVGA: DX shader is not set in DXSetInputLayout: shid = 0x%x\n", shid)),
5301 VERR_INVALID_STATE);
5302 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shid];
5303 AssertReturnStmt(pDXShader->pvDXBC,
5304 LogRelMax(16, ("VMSVGA: DX shader bytecode is not available in DXSetInputLayout: shid = %u\n", shid)),
5305 VERR_INVALID_STATE);
5306 HRESULT hr = pDevice->pDevice->CreateInputLayout(pDXElementLayout->aElementDesc,
5307 pDXElementLayout->cElementDesc,
5308 pDXShader->pvDXBC,
5309 pDXShader->cbDXBC,
5310 &pDXElementLayout->pElementLayout);
5311 AssertReturn(SUCCEEDED(hr), VERR_NO_MEMORY);
5312 }
5313
5314 pDevice->pImmediateContext->IASetInputLayout(pDXElementLayout->pElementLayout);
5315 return VINF_SUCCESS;
5316}
5317
5318
5319static DECLCALLBACK(int) vmsvga3dBackDXSetVertexBuffers(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t startBuffer, uint32_t cVertexBuffer, SVGA3dVertexBuffer const *paVertexBuffer)
5320{
5321 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5322 RT_NOREF(pBackend);
5323
5324 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5325 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5326
5327 /* For each paVertexBuffer[i]:
5328 * If the vertex buffer object does not exist then create it.
5329 * If the surface has been updated by the guest then update the buffer object.
5330 * Use IASetVertexBuffers to set the buffers.
5331 */
5332
5333 ID3D11Buffer *paResources[SVGA3D_DX_MAX_VERTEXBUFFERS];
5334 UINT paStride[SVGA3D_DX_MAX_VERTEXBUFFERS];
5335 UINT paOffset[SVGA3D_DX_MAX_VERTEXBUFFERS];
5336
5337 for (uint32_t i = 0; i < cVertexBuffer; ++i)
5338 {
5339 uint32_t const idxVertexBuffer = startBuffer + i;
5340
5341 /* Get corresponding resource. Create the buffer if does not yet exist. */
5342 if (paVertexBuffer[i].sid != SVGA_ID_INVALID)
5343 {
5344 PVMSVGA3DSURFACE pSurface;
5345 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, paVertexBuffer[i].sid, &pSurface);
5346 AssertRCReturn(rc, rc);
5347
5348 if (pSurface->pBackendSurface == NULL)
5349 {
5350 /* Create the resource and initialize it with the current surface data. */
5351 rc = vmsvga3dBackSurfaceCreateBuffer(pThisCC, pDXContext, pSurface);
5352 AssertRCReturn(rc, rc);
5353 }
5354#if 0
5355 if (pSurface->fDirty)
5356 {
5357 /* Get mobid for the surface and read from the MOB. */
5358 SVGA3dSurfaceImageId imageId;
5359 imageId.sid = paVertexBuffer[i].sid;
5360 imageId.face = 0;
5361 imageId.mipmap = 0;
5362
5363 SVGA3dBox box;
5364 box.x = 0;
5365 box.y = 0;
5366 box.z = 0;
5367 box.w = pSurface->paMipmapLevels[0].mipmapSize.width;
5368 box.h = 1;
5369 box.d = 1;
5370
5371 rc = vmsvgaR3UpdateGBSurface(pThisCC, &imageId, &box);
5372 AssertRCReturn(rc, rc);
5373 }
5374#endif
5375
5376 Assert(pSurface->pBackendSurface->u.pBuffer);
5377 paResources[idxVertexBuffer] = pSurface->pBackendSurface->u.pBuffer;
5378 paStride[idxVertexBuffer] = paVertexBuffer[i].stride;
5379 paOffset[idxVertexBuffer] = paVertexBuffer[i].offset;
5380 }
5381 else
5382 {
5383 paResources[idxVertexBuffer] = NULL;
5384 paStride[idxVertexBuffer] = 0;
5385 paOffset[idxVertexBuffer] = 0;
5386 }
5387
5388 pDXContext->svgaDXContext.inputAssembly.vertexBuffers[idxVertexBuffer].bufferId = paVertexBuffer[i].sid;
5389 pDXContext->svgaDXContext.inputAssembly.vertexBuffers[idxVertexBuffer].stride = paVertexBuffer[i].stride;
5390 pDXContext->svgaDXContext.inputAssembly.vertexBuffers[idxVertexBuffer].offset = paVertexBuffer[i].offset;
5391 }
5392
5393 pDevice->pImmediateContext->IASetVertexBuffers(startBuffer, cVertexBuffer,
5394 &paResources[startBuffer], &paStride[startBuffer], &paOffset[startBuffer]);
5395
5396 return VINF_SUCCESS;
5397}
5398
5399
5400static DECLCALLBACK(int) vmsvga3dBackDXSetIndexBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSurfaceId sid, SVGA3dSurfaceFormat format, uint32_t offset)
5401{
5402 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5403 RT_NOREF(pBackend);
5404
5405 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5406 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5407
5408 /* Get corresponding resource. Create the buffer if does not yet exist. */
5409 ID3D11Buffer *pResource;
5410 DXGI_FORMAT enmDxgiFormat;
5411
5412 if (sid != SVGA_ID_INVALID)
5413 {
5414 PVMSVGA3DSURFACE pSurface;
5415 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
5416 AssertRCReturn(rc, rc);
5417
5418 if (pSurface->pBackendSurface == NULL)
5419 {
5420 /* Create the resource and initialize it with the current surface data. */
5421 rc = vmsvga3dBackSurfaceCreateBuffer(pThisCC, pDXContext, pSurface);
5422 AssertRCReturn(rc, rc);
5423 }
5424#if 0
5425 if (pSurface->fDirty)
5426 {
5427 /* Get mobid for the surface and read from the MOB. */
5428 SVGA3dSurfaceImageId imageId;
5429 imageId.sid = sid;
5430 imageId.face = 0;
5431 imageId.mipmap = 0;
5432
5433 SVGA3dBox box;
5434 box.x = 0;
5435 box.y = 0;
5436 box.z = 0;
5437 box.w = pSurface->paMipmapLevels[0].mipmapSize.width;
5438 box.h = 1;
5439 box.d = 1;
5440
5441 rc = vmsvgaR3UpdateGBSurface(pThisCC, &imageId, &box);
5442 AssertRCReturn(rc, rc);
5443 }
5444#endif
5445 pResource = pSurface->pBackendSurface->u.pBuffer;
5446 enmDxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(format);
5447 AssertReturn(enmDxgiFormat == DXGI_FORMAT_R16_UINT || enmDxgiFormat == DXGI_FORMAT_R32_UINT, VERR_INVALID_PARAMETER);
5448 }
5449 else
5450 {
5451 pResource = NULL;
5452 enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
5453 }
5454
5455 pDevice->pImmediateContext->IASetIndexBuffer(pResource, enmDxgiFormat, offset);
5456 return VINF_SUCCESS;
5457}
5458
5459static D3D11_PRIMITIVE_TOPOLOGY dxTopology(SVGA3dPrimitiveType primitiveType)
5460{
5461 static D3D11_PRIMITIVE_TOPOLOGY const aD3D11PrimitiveTopology[SVGA3D_PRIMITIVE_MAX] =
5462 {
5463 D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED,
5464 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
5465 D3D11_PRIMITIVE_TOPOLOGY_POINTLIST,
5466 D3D11_PRIMITIVE_TOPOLOGY_LINELIST,
5467 D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP,
5468 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
5469 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, /* SVGA3D_PRIMITIVE_TRIANGLEFAN: No FAN in D3D11. */
5470 D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ,
5471 D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ,
5472 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ,
5473 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ,
5474 D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST,
5475 D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST,
5476 D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST,
5477 D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST,
5478 D3D11_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST,
5479 D3D11_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST,
5480 D3D11_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST,
5481 D3D11_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST,
5482 D3D11_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST,
5483 D3D11_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST,
5484 D3D11_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST,
5485 D3D11_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST,
5486 D3D11_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST,
5487 D3D11_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST,
5488 D3D11_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST,
5489 D3D11_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST,
5490 D3D11_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST,
5491 D3D11_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST,
5492 D3D11_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST,
5493 D3D11_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST,
5494 D3D11_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST,
5495 D3D11_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST,
5496 D3D11_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST,
5497 D3D11_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST,
5498 D3D11_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST,
5499 D3D11_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST,
5500 D3D11_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST,
5501 D3D11_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST,
5502 D3D11_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST,
5503 D3D11_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST,
5504 D3D11_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST,
5505 D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST,
5506 };
5507 return aD3D11PrimitiveTopology[primitiveType];
5508}
5509
5510static DECLCALLBACK(int) vmsvga3dBackDXSetTopology(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dPrimitiveType topology)
5511{
5512 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5513 RT_NOREF(pBackend);
5514
5515 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5516 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5517
5518 D3D11_PRIMITIVE_TOPOLOGY const enmTopology = dxTopology(topology);
5519 pDevice->pImmediateContext->IASetPrimitiveTopology(enmTopology);
5520 return VINF_SUCCESS;
5521}
5522
5523
5524static DECLCALLBACK(int) vmsvga3dBackDXSetRenderTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, uint32_t cRenderTargetViewId, SVGA3dRenderTargetViewId const *paRenderTargetViewId)
5525{
5526 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5527 RT_NOREF(pBackend);
5528
5529 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5530 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5531
5532 ID3D11RenderTargetView *papRenderTargetViews[SVGA3D_MAX_RENDER_TARGETS];
5533 RT_ZERO(papRenderTargetViews);
5534 for (uint32_t i = 0; i < cRenderTargetViewId; ++i)
5535 {
5536 SVGA3dRenderTargetViewId const renderTargetViewId = paRenderTargetViewId[i];
5537 if (renderTargetViewId != SVGA3D_INVALID_ID)
5538 {
5539 ASSERT_GUEST_RETURN(renderTargetViewId < pDXContext->pBackendDXContext->cRenderTargetView, VERR_INVALID_PARAMETER);
5540 papRenderTargetViews[i] = pDXContext->pBackendDXContext->papRenderTargetView[renderTargetViewId];
5541 }
5542 }
5543
5544 ID3D11DepthStencilView *pDepthStencilView;
5545 if (depthStencilViewId != SVGA_ID_INVALID)
5546 pDepthStencilView = pDXContext->pBackendDXContext->papDepthStencilView[depthStencilViewId];
5547 else
5548 pDepthStencilView = NULL;
5549
5550#ifdef DX_DEFERRED_SET_RENDER_TARGETS
5551 memcpy(pDXContext->pBackendDXContext->state.papRenderTargetViews, papRenderTargetViews, sizeof(papRenderTargetViews));
5552 pDXContext->pBackendDXContext->state.cRenderTargetViews = cRenderTargetViewId;
5553 pDXContext->pBackendDXContext->state.pDepthStencilView = pDepthStencilView;
5554 pDevice->pImmediateContext->OMSetRenderTargets(0, NULL, NULL);
5555#else
5556 pDevice->pImmediateContext->OMSetRenderTargets(cRenderTargetViewId, papRenderTargetViews, pDepthStencilView);
5557#endif
5558 return VINF_SUCCESS;
5559}
5560
5561
5562static DECLCALLBACK(int) vmsvga3dBackDXSetBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dBlendStateId blendId, float const blendFactor[4], uint32_t sampleMask)
5563{
5564 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5565 RT_NOREF(pBackend);
5566
5567 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5568 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5569
5570 ID3D11BlendState *pBlendState = pDXContext->pBackendDXContext->papBlendState[blendId];
5571 pDevice->pImmediateContext->OMSetBlendState(pBlendState, blendFactor, sampleMask);
5572
5573 pDXContext->svgaDXContext.renderState.blendStateId = blendId;
5574 memcpy(pDXContext->svgaDXContext.renderState.blendFactor, blendFactor, sizeof(blendFactor));
5575 pDXContext->svgaDXContext.renderState.sampleMask = sampleMask;
5576
5577 return VINF_SUCCESS;
5578}
5579
5580
5581static DECLCALLBACK(int) vmsvga3dBackDXSetDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId, uint32_t stencilRef)
5582{
5583 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5584 RT_NOREF(pBackend);
5585
5586 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5587 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5588
5589 ID3D11DepthStencilState *pDepthStencilState = pDXContext->pBackendDXContext->papDepthStencilState[depthStencilId];
5590 pDevice->pImmediateContext->OMSetDepthStencilState(pDepthStencilState, stencilRef);
5591
5592 pDXContext->svgaDXContext.renderState.depthStencilStateId = depthStencilId;
5593 pDXContext->svgaDXContext.renderState.stencilRef = stencilRef;
5594
5595 return VINF_SUCCESS;
5596}
5597
5598
5599static DECLCALLBACK(int) vmsvga3dBackDXSetRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId)
5600{
5601 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5602 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5603 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5604
5605 RT_NOREF(pBackend);
5606
5607 pDevice->pImmediateContext->RSSetState(pDXContext->pBackendDXContext->papRasterizerState[rasterizerId]);
5608 return VINF_SUCCESS;
5609}
5610
5611
5612static DECLCALLBACK(int) vmsvga3dBackDXDefineQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5613{
5614 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5615
5616 RT_NOREF(pBackend, pDXContext);
5617 AssertFailed(); /** @todo Implement */
5618 return VERR_NOT_IMPLEMENTED;
5619}
5620
5621
5622static DECLCALLBACK(int) vmsvga3dBackDXDestroyQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5623{
5624 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5625
5626 RT_NOREF(pBackend, pDXContext);
5627 AssertFailed(); /** @todo Implement */
5628 return VERR_NOT_IMPLEMENTED;
5629}
5630
5631
5632static DECLCALLBACK(int) vmsvga3dBackDXBindQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5633{
5634 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5635
5636 RT_NOREF(pBackend, pDXContext);
5637 AssertFailed(); /** @todo Implement */
5638 return VERR_NOT_IMPLEMENTED;
5639}
5640
5641
5642static DECLCALLBACK(int) vmsvga3dBackDXSetQueryOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5643{
5644 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5645
5646 RT_NOREF(pBackend, pDXContext);
5647 AssertFailed(); /** @todo Implement */
5648 return VERR_NOT_IMPLEMENTED;
5649}
5650
5651
5652static DECLCALLBACK(int) vmsvga3dBackDXBeginQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5653{
5654 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5655
5656 RT_NOREF(pBackend, pDXContext);
5657 AssertFailed(); /** @todo Implement */
5658 return VERR_NOT_IMPLEMENTED;
5659}
5660
5661
5662static DECLCALLBACK(int) vmsvga3dBackDXEndQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5663{
5664 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5665
5666 RT_NOREF(pBackend, pDXContext);
5667 AssertFailed(); /** @todo Implement */
5668 return VERR_NOT_IMPLEMENTED;
5669}
5670
5671
5672static DECLCALLBACK(int) vmsvga3dBackDXReadbackQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5673{
5674 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5675
5676 RT_NOREF(pBackend, pDXContext);
5677 AssertFailed(); /** @todo Implement */
5678 return VERR_NOT_IMPLEMENTED;
5679}
5680
5681
5682static DECLCALLBACK(int) vmsvga3dBackDXSetPredication(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5683{
5684 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5685
5686 RT_NOREF(pBackend, pDXContext);
5687 AssertFailed(); /** @todo Implement */
5688 return VERR_NOT_IMPLEMENTED;
5689}
5690
5691
5692static DECLCALLBACK(int) vmsvga3dBackDXSetSOTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t cSOTarget, SVGA3dSoTarget const *paSoTarget)
5693{
5694 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5695 RT_NOREF(pBackend);
5696
5697 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5698 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5699
5700 /* For each paSoTarget[i]:
5701 * If the stream outout buffer object does not exist then create it.
5702 * If the surface has been updated by the guest then update the buffer object.
5703 * Use SOSetTargets to set the buffers.
5704 */
5705
5706 ID3D11Buffer *paResource[SVGA3D_DX_MAX_SOTARGETS];
5707 UINT paOffset[SVGA3D_DX_MAX_SOTARGETS];
5708
5709 /* Always re-bind all 4 SO targets. They can be NULL. */
5710 for (uint32_t i = 0; i < SVGA3D_DX_MAX_SOTARGETS; ++i)
5711 {
5712 /* Get corresponding resource. Create the buffer if does not yet exist. */
5713 if (i < cSOTarget && paSoTarget[i].sid != SVGA_ID_INVALID)
5714 {
5715 PVMSVGA3DSURFACE pSurface;
5716 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, paSoTarget[i].sid, &pSurface);
5717 AssertRCReturn(rc, rc);
5718
5719 if (pSurface->pBackendSurface == NULL)
5720 {
5721 /* Create the resource. */
5722 rc = vmsvga3dBackSurfaceCreateSoBuffer(pThisCC, pDXContext, pSurface);
5723 AssertRCReturn(rc, rc);
5724 }
5725
5726 /** @todo How paSoTarget[i].sizeInBytes is used? Maybe when the buffer is created? */
5727 paResource[i] = pSurface->pBackendSurface->u.pBuffer;
5728 paOffset[i] = paSoTarget[i].offset;
5729
5730 /** @todo This should be in the caller. */
5731 pDXContext->svgaDXContext.streamOut.targets[i] = paSoTarget[i].sid;
5732 }
5733 else
5734 {
5735 paResource[i] = NULL;
5736 paOffset[i] = 0;
5737
5738 /** @todo This should be in the caller. */
5739 pDXContext->svgaDXContext.streamOut.targets[i] = SVGA_ID_INVALID;
5740 }
5741 }
5742
5743 pDevice->pImmediateContext->SOSetTargets(SVGA3D_DX_MAX_SOTARGETS, paResource, paOffset);
5744
5745 pDXContext->pBackendDXContext->cSOTarget = cSOTarget;
5746
5747 return VINF_SUCCESS;
5748}
5749
5750
5751static DECLCALLBACK(int) vmsvga3dBackDXSetViewports(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t cViewport, SVGA3dViewport const *paViewport)
5752{
5753 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5754 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5755 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5756
5757 RT_NOREF(pBackend);
5758
5759 /* D3D11_VIEWPORT is identical to SVGA3dViewport. */
5760 D3D11_VIEWPORT *pViewports = (D3D11_VIEWPORT *)paViewport;
5761
5762 pDevice->pImmediateContext->RSSetViewports(cViewport, pViewports);
5763 return VINF_SUCCESS;
5764}
5765
5766
5767static DECLCALLBACK(int) vmsvga3dBackDXSetScissorRects(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t cRect, SVGASignedRect const *paRect)
5768{
5769 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5770 RT_NOREF(pBackend);
5771
5772 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5773 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5774
5775 /* D3D11_RECT is identical to SVGASignedRect. */
5776 D3D11_RECT *pRects = (D3D11_RECT *)paRect;
5777
5778 pDevice->pImmediateContext->RSSetScissorRects(cRect, pRects);
5779 return VINF_SUCCESS;
5780}
5781
5782
5783static DECLCALLBACK(int) vmsvga3dBackDXClearRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGA3dRGBAFloat const *pRGBA)
5784{
5785 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5786 RT_NOREF(pBackend);
5787
5788 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5789 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5790
5791 ID3D11RenderTargetView *pRenderTargetView = pDXContext->pBackendDXContext->papRenderTargetView[renderTargetViewId];
5792 AssertReturn(pRenderTargetView, VERR_INVALID_STATE);
5793 pDevice->pImmediateContext->ClearRenderTargetView(pRenderTargetView, pRGBA->value);
5794 return VINF_SUCCESS;
5795}
5796
5797
5798static DECLCALLBACK(int) vmsvga3dBackDXClearDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t flags, SVGA3dDepthStencilViewId depthStencilViewId, float depth, uint8_t stencil)
5799{
5800 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5801 RT_NOREF(pBackend);
5802
5803 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5804 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5805
5806 ID3D11DepthStencilView *pDepthStencilView = pDXContext->pBackendDXContext->papDepthStencilView[depthStencilViewId];
5807 AssertReturn(pDepthStencilView, VERR_INVALID_STATE);
5808 pDevice->pImmediateContext->ClearDepthStencilView(pDepthStencilView, flags, depth, stencil);
5809 return VINF_SUCCESS;
5810}
5811
5812
5813static DECLCALLBACK(int) vmsvga3dBackDXPredCopyRegion(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSurfaceId dstSid, uint32_t dstSubResource, SVGA3dSurfaceId srcSid, uint32_t srcSubResource, SVGA3dCopyBox const *pBox)
5814{
5815 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5816 RT_NOREF(pBackend);
5817
5818 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5819 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5820
5821 PVMSVGA3DSURFACE pSrcSurface;
5822 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, srcSid, &pSrcSurface);
5823 AssertRCReturn(rc, rc);
5824
5825 PVMSVGA3DSURFACE pDstSurface;
5826 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, dstSid, &pDstSurface);
5827 AssertRCReturn(rc, rc);
5828
5829 if (pSrcSurface->pBackendSurface == NULL)
5830 {
5831 /* Create the resource. */
5832 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSrcSurface);
5833 AssertRCReturn(rc, rc);
5834 }
5835
5836 if (pDstSurface->pBackendSurface == NULL)
5837 {
5838 /* Create the resource. */
5839 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pDstSurface);
5840 AssertRCReturn(rc, rc);
5841 }
5842
5843 LogFunc(("cid %d: src cid %d%s -> dst cid %d%s\n",
5844 pDXContext->cid, pSrcSurface->idAssociatedContext,
5845 (pSrcSurface->surfaceFlags & SVGA3D_SURFACE_SCREENTARGET) ? " st" : "",
5846 pDstSurface->idAssociatedContext,
5847 (pDstSurface->surfaceFlags & SVGA3D_SURFACE_SCREENTARGET) ? " st" : ""));
5848
5849 /* Clip the box. */
5850 /** @todo Use [src|dst]SubResource to index p[Src|Dst]Surface->paMipmapLevels array directly. */
5851 uint32_t iSrcFace;
5852 uint32_t iSrcMipmap;
5853 vmsvga3dCalcMipmapAndFace(pSrcSurface->cLevels, srcSubResource, &iSrcMipmap, &iSrcFace);
5854
5855 uint32_t iDstFace;
5856 uint32_t iDstMipmap;
5857 vmsvga3dCalcMipmapAndFace(pDstSurface->cLevels, dstSubResource, &iDstMipmap, &iDstFace);
5858
5859 PVMSVGA3DMIPMAPLEVEL pSrcMipLevel;
5860 rc = vmsvga3dMipmapLevel(pSrcSurface, iSrcFace, iSrcMipmap, &pSrcMipLevel);
5861 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
5862
5863 PVMSVGA3DMIPMAPLEVEL pDstMipLevel;
5864 rc = vmsvga3dMipmapLevel(pDstSurface, iDstFace, iDstMipmap, &pDstMipLevel);
5865 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
5866
5867 SVGA3dCopyBox clipBox = *pBox;
5868 vmsvgaR3ClipCopyBox(&pSrcMipLevel->mipmapSize, &pDstMipLevel->mipmapSize, &clipBox);
5869
5870 UINT DstSubresource = dstSubResource;
5871 UINT DstX = clipBox.x;
5872 UINT DstY = clipBox.y;
5873 UINT DstZ = clipBox.z;
5874
5875 UINT SrcSubresource = srcSubResource;
5876 D3D11_BOX SrcBox;
5877 SrcBox.left = clipBox.srcx;
5878 SrcBox.top = clipBox.srcy;
5879 SrcBox.front = clipBox.srcz;
5880 SrcBox.right = clipBox.srcx + clipBox.w;
5881 SrcBox.bottom = clipBox.srcy + clipBox.h;
5882 SrcBox.back = clipBox.srcz + clipBox.d;
5883
5884 ID3D11Resource *pDstResource;
5885 ID3D11Resource *pSrcResource;
5886
5887 pDstResource = dxResource(pThisCC->svga.p3dState, pDstSurface, pDXContext);
5888 pSrcResource = dxResource(pThisCC->svga.p3dState, pSrcSurface, pDXContext);
5889
5890 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
5891 pSrcResource, SrcSubresource, &SrcBox);
5892
5893 pDstSurface->pBackendSurface->cidDrawing = pDXContext->cid;
5894 return VINF_SUCCESS;
5895}
5896
5897
5898static DECLCALLBACK(int) vmsvga3dBackDXPredCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5899{
5900 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5901
5902 RT_NOREF(pBackend, pDXContext);
5903 AssertFailed(); /** @todo Implement */
5904 return VERR_NOT_IMPLEMENTED;
5905}
5906
5907
5908static DECLCALLBACK(int) vmsvga3dBackDXPresentBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5909{
5910 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5911
5912 RT_NOREF(pBackend, pDXContext);
5913 AssertFailed(); /** @todo Implement */
5914 return VERR_NOT_IMPLEMENTED;
5915}
5916
5917
5918static DECLCALLBACK(int) vmsvga3dBackDXGenMips(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId)
5919{
5920 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5921 RT_NOREF(pBackend);
5922
5923 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5924 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5925
5926 ID3D11ShaderResourceView *pShaderResourceView = pDXContext->pBackendDXContext->papShaderResourceView[shaderResourceViewId];
5927 AssertReturn(pShaderResourceView, VERR_INVALID_STATE);
5928
5929 uint32_t const sid = dxGetShaderResourceViewSid(pDXContext, shaderResourceViewId);
5930
5931 PVMSVGA3DSURFACE pSurface;
5932 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
5933 AssertRCReturn(rc, rc);
5934 AssertReturn(pSurface->pBackendSurface, VERR_INVALID_STATE);
5935
5936 pDevice->pImmediateContext->GenerateMips(pShaderResourceView);
5937
5938 pSurface->pBackendSurface->cidDrawing = pDXContext->cid;
5939 return VINF_SUCCESS;
5940}
5941
5942
5943static int dxDefineShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId, SVGACOTableDXSRViewEntry const *pEntry)
5944{
5945 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
5946 PVMSVGA3DSURFACE pSurface;
5947 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
5948 AssertRCReturn(rc, rc);
5949
5950 if (pSurface->pBackendSurface == NULL)
5951 {
5952 /* Create the actual texture. */
5953 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSurface);
5954 AssertRCReturn(rc, rc);
5955 }
5956
5957 HRESULT hr = dxShaderResourceViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pDXContext->pBackendDXContext->papShaderResourceView[shaderResourceViewId]);
5958 if (SUCCEEDED(hr))
5959 return VINF_SUCCESS;
5960 return VERR_INVALID_STATE;
5961}
5962
5963
5964static DECLCALLBACK(int) vmsvga3dBackDXDefineShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId, SVGACOTableDXSRViewEntry const *pEntry)
5965{
5966 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5967 RT_NOREF(pBackend);
5968
5969 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5970 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5971
5972 return dxDefineShaderResourceView(pThisCC, pDXContext, shaderResourceViewId, pEntry);
5973}
5974
5975
5976static DECLCALLBACK(int) vmsvga3dBackDXDestroyShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId)
5977{
5978 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5979 RT_NOREF(pBackend);
5980
5981 D3D_RELEASE(pDXContext->pBackendDXContext->papShaderResourceView[shaderResourceViewId]);
5982 return VINF_SUCCESS;
5983}
5984
5985
5986static int dxDefineRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGACOTableDXRTViewEntry const *pEntry)
5987{
5988 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
5989 PVMSVGA3DSURFACE pSurface;
5990 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
5991 AssertRCReturn(rc, rc);
5992
5993 if (pSurface->pBackendSurface == NULL)
5994 {
5995 /* Create the actual texture. */
5996 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSurface);
5997 AssertRCReturn(rc, rc);
5998 }
5999
6000 HRESULT hr = dxRenderTargetViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pDXContext->pBackendDXContext->papRenderTargetView[renderTargetViewId]);
6001 if (SUCCEEDED(hr))
6002 return VINF_SUCCESS;
6003
6004 return VERR_INVALID_STATE;
6005}
6006
6007
6008static DECLCALLBACK(int) vmsvga3dBackDXDefineRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGACOTableDXRTViewEntry const *pEntry)
6009{
6010 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6011 RT_NOREF(pBackend);
6012
6013 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6014 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6015
6016 return dxDefineRenderTargetView(pThisCC, pDXContext, renderTargetViewId, pEntry);
6017}
6018
6019
6020static DECLCALLBACK(int) vmsvga3dBackDXDestroyRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId)
6021{
6022 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6023 RT_NOREF(pBackend);
6024
6025 D3D_RELEASE(pDXContext->pBackendDXContext->papRenderTargetView[renderTargetViewId]);
6026 return VINF_SUCCESS;
6027}
6028
6029
6030static int dxDefineDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, SVGACOTableDXDSViewEntry const *pEntry)
6031{
6032 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
6033 PVMSVGA3DSURFACE pSurface;
6034 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
6035 AssertRCReturn(rc, rc);
6036
6037 if ( pSurface->pBackendSurface != NULL
6038 && pDXContext->cid != pSurface->idAssociatedContext)
6039 {
6040 /* Supposed to be per context. Sometimes the guest reuses the texture in another context. */
6041 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
6042 }
6043
6044 if (pSurface->pBackendSurface == NULL)
6045 {
6046 /* Create the actual texture. */
6047 rc = vmsvga3dBackSurfaceCreateDepthStencilTexture(pThisCC, pDXContext, pSurface);
6048 AssertRCReturn(rc, rc);
6049 }
6050
6051 HRESULT hr = dxDepthStencilViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pDXContext->pBackendDXContext->papDepthStencilView[depthStencilViewId]);
6052 if (SUCCEEDED(hr))
6053 return VINF_SUCCESS;
6054 return VERR_INVALID_STATE;
6055}
6056
6057static DECLCALLBACK(int) vmsvga3dBackDXDefineDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, SVGACOTableDXDSViewEntry const *pEntry)
6058{
6059 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6060 RT_NOREF(pBackend);
6061
6062 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6063 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6064
6065 return dxDefineDepthStencilView(pThisCC, pDXContext, depthStencilViewId, pEntry);
6066}
6067
6068
6069static DECLCALLBACK(int) vmsvga3dBackDXDestroyDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId)
6070{
6071 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6072 RT_NOREF(pBackend);
6073
6074 D3D_RELEASE(pDXContext->pBackendDXContext->papDepthStencilView[depthStencilViewId]);
6075 return VINF_SUCCESS;
6076}
6077
6078
6079static int dxDefineElementLayout(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId, SVGACOTableDXElementLayoutEntry const *pEntry)
6080{
6081 DXELEMENTLAYOUT *pDXElementLayout = &pDXContext->pBackendDXContext->paElementLayout[elementLayoutId];
6082 D3D_RELEASE(pDXElementLayout->pElementLayout);
6083
6084 /* Semantic name is not interpreted by D3D, therefore arbitrary names can be used
6085 * if they are consistent between the element layout and shader input signature.
6086 * "In general, data passed between pipeline stages is completely generic and is not uniquely
6087 * interpreted by the system; arbitrary semantics are allowed ..."
6088 *
6089 * However D3D runtime insists that "SemanticName string ("POSITIO1") cannot end with a number."
6090 *
6091 * System-Value semantics ("SV_*") between shaders require proper names of course.
6092 * But they are irrelevant for input attributes.
6093 */
6094 pDXElementLayout->cElementDesc = pEntry->numDescs;
6095 for (uint32_t i = 0; i < pEntry->numDescs; ++i)
6096 {
6097 D3D11_INPUT_ELEMENT_DESC *pDst = &pDXElementLayout->aElementDesc[i];
6098 SVGA3dInputElementDesc const *pSrc = &pEntry->descs[i];
6099 pDst->SemanticName = "ATTRIB";
6100 pDst->SemanticIndex = i; /// @todo 'pSrc->inputRegister' is unused, maybe it should somehow.
6101 pDst->Format = vmsvgaDXSurfaceFormat2Dxgi(pSrc->format);
6102 AssertReturn(pDst->Format != DXGI_FORMAT_UNKNOWN, VERR_NOT_IMPLEMENTED);
6103 pDst->InputSlot = pSrc->inputSlot;
6104 pDst->AlignedByteOffset = pSrc->alignedByteOffset;
6105 pDst->InputSlotClass = (D3D11_INPUT_CLASSIFICATION)pSrc->inputSlotClass;
6106 pDst->InstanceDataStepRate = pSrc->instanceDataStepRate;
6107 }
6108
6109 return VINF_SUCCESS;
6110}
6111
6112
6113static DECLCALLBACK(int) vmsvga3dBackDXDefineElementLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId, SVGACOTableDXElementLayoutEntry const *pEntry)
6114{
6115 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6116 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6117 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6118
6119 RT_NOREF(pBackend);
6120
6121 /* Not much can be done here because ID3D11Device::CreateInputLayout requires
6122 * a pShaderBytecodeWithInputSignature which is not known at this moment.
6123 * InputLayout object will be created in SVGA_3D_CMD_DX_SET_INPUT_LAYOUT.
6124 */
6125
6126 Assert(elementLayoutId == pEntry->elid);
6127
6128 return dxDefineElementLayout(pDXContext, elementLayoutId, pEntry);
6129}
6130
6131
6132static DECLCALLBACK(int) vmsvga3dBackDXDestroyElementLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6133{
6134 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6135
6136 RT_NOREF(pBackend, pDXContext);
6137 AssertFailed(); /** @todo Implement */
6138 return VERR_NOT_IMPLEMENTED;
6139}
6140
6141
6142static int dxDefineBlendState(PVMSVGA3DDXCONTEXT pDXContext,
6143 SVGA3dBlendStateId blendId, SVGACOTableDXBlendStateEntry const *pEntry)
6144{
6145 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6146 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6147
6148 HRESULT hr = dxBlendStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papBlendState[blendId]);
6149 if (SUCCEEDED(hr))
6150 return VINF_SUCCESS;
6151 return VERR_INVALID_STATE;
6152}
6153
6154static DECLCALLBACK(int) vmsvga3dBackDXDefineBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
6155 SVGA3dBlendStateId blendId, SVGACOTableDXBlendStateEntry const *pEntry)
6156{
6157 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6158 RT_NOREF(pBackend);
6159
6160 return dxDefineBlendState(pDXContext, blendId, pEntry);
6161}
6162
6163
6164static DECLCALLBACK(int) vmsvga3dBackDXDestroyBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6165{
6166 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6167
6168 RT_NOREF(pBackend, pDXContext);
6169 AssertFailed(); /** @todo Implement */
6170 return VERR_NOT_IMPLEMENTED;
6171}
6172
6173
6174static int dxDefineDepthStencilState(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId, SVGACOTableDXDepthStencilEntry const *pEntry)
6175{
6176 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6177 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6178
6179 HRESULT hr = dxDepthStencilStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papDepthStencilState[depthStencilId]);
6180 if (SUCCEEDED(hr))
6181 return VINF_SUCCESS;
6182 return VERR_INVALID_STATE;
6183}
6184
6185
6186static DECLCALLBACK(int) vmsvga3dBackDXDefineDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId, SVGACOTableDXDepthStencilEntry const *pEntry)
6187{
6188 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6189 RT_NOREF(pBackend);
6190
6191 return dxDefineDepthStencilState(pDXContext, depthStencilId, pEntry);
6192}
6193
6194
6195static DECLCALLBACK(int) vmsvga3dBackDXDestroyDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6196{
6197 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6198
6199 RT_NOREF(pBackend, pDXContext);
6200 AssertFailed(); /** @todo Implement */
6201 return VERR_NOT_IMPLEMENTED;
6202}
6203
6204
6205static int dxDefineRasterizerState(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId, SVGACOTableDXRasterizerStateEntry const *pEntry)
6206{
6207 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6208 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6209
6210 HRESULT hr = dxRasterizerStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papRasterizerState[rasterizerId]);
6211 if (SUCCEEDED(hr))
6212 return VINF_SUCCESS;
6213 return VERR_INVALID_STATE;
6214}
6215
6216
6217static DECLCALLBACK(int) vmsvga3dBackDXDefineRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId, SVGACOTableDXRasterizerStateEntry const *pEntry)
6218{
6219 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6220 RT_NOREF(pBackend);
6221
6222 return dxDefineRasterizerState(pDXContext, rasterizerId, pEntry);
6223}
6224
6225
6226static DECLCALLBACK(int) vmsvga3dBackDXDestroyRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6227{
6228 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6229
6230 RT_NOREF(pBackend, pDXContext);
6231 AssertFailed(); /** @todo Implement */
6232 return VERR_NOT_IMPLEMENTED;
6233}
6234
6235
6236static int dxDefineSamplerState(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSamplerId samplerId, SVGACOTableDXSamplerEntry const *pEntry)
6237{
6238 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6239 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6240
6241 HRESULT hr = dxSamplerStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papSamplerState[samplerId]);
6242 if (SUCCEEDED(hr))
6243 return VINF_SUCCESS;
6244 return VERR_INVALID_STATE;
6245}
6246
6247
6248static DECLCALLBACK(int) vmsvga3dBackDXDefineSamplerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSamplerId samplerId, SVGACOTableDXSamplerEntry const *pEntry)
6249{
6250 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6251 RT_NOREF(pBackend);
6252
6253 return dxDefineSamplerState(pDXContext, samplerId, pEntry);
6254}
6255
6256
6257static DECLCALLBACK(int) vmsvga3dBackDXDestroySamplerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6258{
6259 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6260
6261 RT_NOREF(pBackend, pDXContext);
6262 AssertFailed(); /** @todo Implement */
6263 return VERR_NOT_IMPLEMENTED;
6264}
6265
6266
6267
6268static int dxDefineShader(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, SVGACOTableDXShaderEntry const *pEntry)
6269{
6270 /** @todo A common approach for creation of COTable backend objects: runtime, empty DX COTable, live DX COTable. */
6271 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
6272 if (pDXShader->enmShaderType == SVGA3D_SHADERTYPE_INVALID)
6273 {
6274 /* Init the shader structure. */
6275 pDXShader->enmShaderType = pEntry->type;
6276 pDXShader->soid = SVGA_ID_INVALID;
6277 }
6278
6279 PVMSVGA3DSHADER pShader = &pDXContext->paShader[shaderId];
6280 pShader->u.pvBackendShader = pDXShader;
6281
6282 return VINF_SUCCESS;
6283}
6284
6285
6286static int dxDestroyShader(DXSHADER *pDXShader)
6287{
6288 pDXShader->enmShaderType = SVGA3D_SHADERTYPE_INVALID;
6289 D3D_RELEASE(pDXShader->pShader);
6290 RTMemFree(pDXShader->pvDXBC);
6291 pDXShader->pvDXBC = NULL;
6292 pDXShader->cbDXBC = 0;
6293 pDXShader->soid = SVGA_ID_INVALID;
6294 return VINF_SUCCESS;
6295}
6296
6297
6298static DECLCALLBACK(int) vmsvga3dBackDXDefineShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, SVGACOTableDXShaderEntry const *pEntry)
6299{
6300 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6301 RT_NOREF(pBackend);
6302
6303 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
6304 dxDestroyShader(pDXShader);
6305
6306 return dxDefineShader(pDXContext, shaderId, pEntry);
6307}
6308
6309
6310static DECLCALLBACK(int) vmsvga3dBackDXDestroyShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId)
6311{
6312 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6313 RT_NOREF(pBackend);
6314
6315 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
6316 dxDestroyShader(pDXShader);
6317
6318 return VINF_SUCCESS;
6319}
6320
6321
6322static DECLCALLBACK(int) vmsvga3dBackDXBindShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSHADER pShader, void const *pvShaderBytecode)
6323{
6324 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6325 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6326 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6327
6328 RT_NOREF(pBackend);
6329
6330 int rc = VINF_SUCCESS;
6331
6332 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[pShader->id];
6333 Assert(pDXShader->enmShaderType == pShader->type);
6334
6335 if (pDXShader->pvDXBC)
6336 {
6337 RTMemFree(pDXShader->pvDXBC);
6338 pDXShader->pvDXBC = NULL;
6339 pDXShader->cbDXBC = 0;
6340 }
6341
6342 if (pvShaderBytecode)
6343 {
6344 Log(("Shader: cid=%u shid=%u type=%d\n", pDXContext->cid, pShader->id, pDXShader->enmShaderType));
6345
6346 rc = DXShaderCreateDXBC(&pShader->shaderInfo, &pDXShader->pvDXBC, &pDXShader->cbDXBC);
6347 if (RT_SUCCESS(rc))
6348 {
6349#ifdef LOG_ENABLED
6350 if (pBackend->pfnD3DDisassemble && LogIs6Enabled())
6351 {
6352 ID3D10Blob *pBlob = 0;
6353 HRESULT hr2 = pBackend->pfnD3DDisassemble(pDXShader->pvDXBC, pDXShader->cbDXBC, 0, NULL, &pBlob);
6354 if (SUCCEEDED(hr2) && pBlob && pBlob->GetBufferSize())
6355 Log6(("%s\n", pBlob->GetBufferPointer()));
6356 else
6357 AssertFailed();
6358 D3D_RELEASE(pBlob);
6359 }
6360#endif
6361
6362 HRESULT hr = dxShaderCreate(pDXContext, pShader, pDXShader);
6363 if (SUCCEEDED(hr))
6364 {
6365 }
6366 else
6367 rc = VERR_INVALID_STATE;
6368 }
6369 else
6370 rc = VERR_NO_MEMORY;
6371 }
6372
6373 return rc;
6374}
6375
6376
6377static DECLCALLBACK(int) vmsvga3dBackDXDefineStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid, SVGACOTableDXStreamOutputEntry const *pEntry)
6378{
6379 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6380 RT_NOREF(pBackend);
6381
6382 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
6383 dxDestroyStreamOutput(pDXStreamOutput);
6384
6385 return dxDefineStreamOutput(pDXContext, soid, pEntry);
6386}
6387
6388
6389static DECLCALLBACK(int) vmsvga3dBackDXDestroyStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid)
6390{
6391 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6392 RT_NOREF(pBackend);
6393
6394 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
6395 dxDestroyStreamOutput(pDXStreamOutput);
6396
6397 return VINF_SUCCESS;
6398}
6399
6400
6401static DECLCALLBACK(int) vmsvga3dBackDXSetStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid)
6402{
6403 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6404 RT_NOREF(pBackend, pDXContext, soid);
6405
6406 return VINF_SUCCESS;
6407}
6408
6409
6410static int dxCOTableRealloc(void **ppvCOTable, uint32_t *pcCOTable, uint32_t cbEntry, uint32_t cEntries, uint32_t cValidEntries)
6411{
6412 uint32_t const cCOTableCurrent = *pcCOTable;
6413
6414 if (*pcCOTable != cEntries)
6415 {
6416 /* Grow/shrink the array. */
6417 if (cEntries)
6418 {
6419 void *pvNew = RTMemRealloc(*ppvCOTable, cEntries * cbEntry);
6420 AssertReturn(pvNew, VERR_NO_MEMORY);
6421 *ppvCOTable = pvNew;
6422 }
6423 else
6424 {
6425 RTMemFree(*ppvCOTable);
6426 *ppvCOTable = NULL;
6427 }
6428
6429 *pcCOTable = cEntries;
6430 }
6431
6432 if (*ppvCOTable)
6433 {
6434 uint32_t const cEntriesToKeep = RT_MIN(cCOTableCurrent, cValidEntries);
6435 memset((uint8_t *)(*ppvCOTable) + cEntriesToKeep * cbEntry, 0, (cEntries - cEntriesToKeep) * cbEntry);
6436 }
6437
6438 return VINF_SUCCESS;
6439}
6440
6441static DECLCALLBACK(int) vmsvga3dBackDXSetCOTable(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableType type, uint32_t cValidEntries)
6442{
6443 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6444 RT_NOREF(pBackend);
6445
6446 VMSVGA3DBACKENDDXCONTEXT *pBackendDXContext = pDXContext->pBackendDXContext;
6447
6448 int rc = VINF_SUCCESS;
6449
6450 /*
6451 * 1) Release current backend table, if exists;
6452 * 2) Reallocate memory for the new backend table;
6453 * 3) If cValidEntries is not zero, then re-define corresponding backend table elements.
6454 */
6455 switch (type)
6456 {
6457 case SVGA_COTABLE_RTVIEW:
6458 /* Clear current entries. */
6459 if (pBackendDXContext->papRenderTargetView)
6460 {
6461 for (uint32_t i = cValidEntries; i < pBackendDXContext->cRenderTargetView; ++i)
6462 D3D_RELEASE(pBackendDXContext->papRenderTargetView[i]);
6463 }
6464
6465 rc = dxCOTableRealloc((void **)&pBackendDXContext->papRenderTargetView, &pBackendDXContext->cRenderTargetView,
6466 sizeof(pBackendDXContext->papRenderTargetView[0]), pDXContext->cot.cRTView, cValidEntries);
6467 AssertRCBreak(rc);
6468
6469 for (uint32_t i = 0; i < cValidEntries; ++i)
6470 {
6471 SVGACOTableDXRTViewEntry const *pEntry = &pDXContext->cot.paRTView[i];
6472 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6473 continue; /* Skip uninitialized entry. */
6474
6475 dxDefineRenderTargetView(pThisCC, pDXContext, i, pEntry);
6476 }
6477 break;
6478 case SVGA_COTABLE_DSVIEW:
6479 if (pBackendDXContext->papDepthStencilView)
6480 {
6481 for (uint32_t i = cValidEntries; i < pBackendDXContext->cDepthStencilView; ++i)
6482 D3D_RELEASE(pBackendDXContext->papDepthStencilView[i]);
6483 }
6484
6485 rc = dxCOTableRealloc((void **)&pBackendDXContext->papDepthStencilView, &pBackendDXContext->cDepthStencilView,
6486 sizeof(pBackendDXContext->papDepthStencilView[0]), pDXContext->cot.cDSView, cValidEntries);
6487 AssertRCBreak(rc);
6488
6489 for (uint32_t i = 0; i < cValidEntries; ++i)
6490 {
6491 SVGACOTableDXDSViewEntry const *pEntry = &pDXContext->cot.paDSView[i];
6492 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6493 continue; /* Skip uninitialized entry. */
6494
6495 dxDefineDepthStencilView(pThisCC, pDXContext, i, pEntry);
6496 }
6497 break;
6498 case SVGA_COTABLE_SRVIEW:
6499 if (pBackendDXContext->papShaderResourceView)
6500 {
6501 for (uint32_t i = cValidEntries; i < pBackendDXContext->cShaderResourceView; ++i)
6502 D3D_RELEASE(pBackendDXContext->papShaderResourceView[i]);
6503 }
6504
6505 rc = dxCOTableRealloc((void **)&pBackendDXContext->papShaderResourceView, &pBackendDXContext->cShaderResourceView,
6506 sizeof(pBackendDXContext->papShaderResourceView[0]), pDXContext->cot.cSRView, cValidEntries);
6507 AssertRCBreak(rc);
6508
6509 for (uint32_t i = 0; i < cValidEntries; ++i)
6510 {
6511 SVGACOTableDXSRViewEntry const *pEntry = &pDXContext->cot.paSRView[i];
6512 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6513 continue; /* Skip uninitialized entry. */
6514
6515 dxDefineShaderResourceView(pThisCC, pDXContext, i, pEntry);
6516 }
6517 break;
6518 case SVGA_COTABLE_ELEMENTLAYOUT:
6519 if (pBackendDXContext->paElementLayout)
6520 {
6521 for (uint32_t i = cValidEntries; i < pBackendDXContext->cElementLayout; ++i)
6522 D3D_RELEASE(pBackendDXContext->paElementLayout[i].pElementLayout);
6523 }
6524
6525 rc = dxCOTableRealloc((void **)&pBackendDXContext->paElementLayout, &pBackendDXContext->cElementLayout,
6526 sizeof(pBackendDXContext->paElementLayout[0]), pDXContext->cot.cElementLayout, cValidEntries);
6527 AssertRCBreak(rc);
6528
6529 for (uint32_t i = 0; i < cValidEntries; ++i)
6530 {
6531 SVGACOTableDXElementLayoutEntry const *pEntry = &pDXContext->cot.paElementLayout[i];
6532 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6533 continue; /* Skip uninitialized entry. */
6534
6535 dxDefineElementLayout(pDXContext, i, pEntry);
6536 }
6537 break;
6538 case SVGA_COTABLE_BLENDSTATE:
6539 if (pBackendDXContext->papBlendState)
6540 {
6541 for (uint32_t i = cValidEntries; i < pBackendDXContext->cBlendState; ++i)
6542 D3D_RELEASE(pBackendDXContext->papBlendState[i]);
6543 }
6544
6545 rc = dxCOTableRealloc((void **)&pBackendDXContext->papBlendState, &pBackendDXContext->cBlendState,
6546 sizeof(pBackendDXContext->papBlendState[0]), pDXContext->cot.cBlendState, cValidEntries);
6547 AssertRCBreak(rc);
6548
6549 for (uint32_t i = 0; i < cValidEntries; ++i)
6550 {
6551 SVGACOTableDXBlendStateEntry const *pEntry = &pDXContext->cot.paBlendState[i];
6552 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6553 continue; /* Skip uninitialized entry. */
6554
6555 dxDefineBlendState(pDXContext, i, pEntry);
6556 }
6557 break;
6558 case SVGA_COTABLE_DEPTHSTENCIL:
6559 if (pBackendDXContext->papDepthStencilState)
6560 {
6561 for (uint32_t i = cValidEntries; i < pBackendDXContext->cDepthStencilState; ++i)
6562 D3D_RELEASE(pBackendDXContext->papDepthStencilState[i]);
6563 }
6564
6565 rc = dxCOTableRealloc((void **)&pBackendDXContext->papDepthStencilState, &pBackendDXContext->cDepthStencilState,
6566 sizeof(pBackendDXContext->papDepthStencilState[0]), pDXContext->cot.cDepthStencil, cValidEntries);
6567 AssertRCBreak(rc);
6568
6569 for (uint32_t i = 0; i < cValidEntries; ++i)
6570 {
6571 SVGACOTableDXDepthStencilEntry const *pEntry = &pDXContext->cot.paDepthStencil[i];
6572 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6573 continue; /* Skip uninitialized entry. */
6574
6575 dxDefineDepthStencilState(pDXContext, i, pEntry);
6576 }
6577 break;
6578 case SVGA_COTABLE_RASTERIZERSTATE:
6579 if (pBackendDXContext->papRasterizerState)
6580 {
6581 for (uint32_t i = cValidEntries; i < pBackendDXContext->cRasterizerState; ++i)
6582 D3D_RELEASE(pBackendDXContext->papRasterizerState[i]);
6583 }
6584
6585 rc = dxCOTableRealloc((void **)&pBackendDXContext->papRasterizerState, &pBackendDXContext->cRasterizerState,
6586 sizeof(pBackendDXContext->papRasterizerState[0]), pDXContext->cot.cRasterizerState, cValidEntries);
6587 AssertRCBreak(rc);
6588
6589 for (uint32_t i = 0; i < cValidEntries; ++i)
6590 {
6591 SVGACOTableDXRasterizerStateEntry const *pEntry = &pDXContext->cot.paRasterizerState[i];
6592 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6593 continue; /* Skip uninitialized entry. */
6594
6595 dxDefineRasterizerState(pDXContext, i, pEntry);
6596 }
6597 break;
6598 case SVGA_COTABLE_SAMPLER:
6599 if (pBackendDXContext->papSamplerState)
6600 {
6601 for (uint32_t i = cValidEntries; i < pBackendDXContext->cSamplerState; ++i)
6602 D3D_RELEASE(pBackendDXContext->papSamplerState[i]);
6603 }
6604
6605 rc = dxCOTableRealloc((void **)&pBackendDXContext->papSamplerState, &pBackendDXContext->cSamplerState,
6606 sizeof(pBackendDXContext->papSamplerState[0]), pDXContext->cot.cSampler, cValidEntries);
6607 AssertRCBreak(rc);
6608
6609 for (uint32_t i = 0; i < cValidEntries; ++i)
6610 {
6611 SVGACOTableDXSamplerEntry const *pEntry = &pDXContext->cot.paSampler[i];
6612 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6613 continue; /* Skip uninitialized entry. */
6614
6615 dxDefineSamplerState(pDXContext, i, pEntry);
6616 }
6617 break;
6618 case SVGA_COTABLE_STREAMOUTPUT:
6619 if (pBackendDXContext->paStreamOutput)
6620 {
6621 for (uint32_t i = cValidEntries; i < pBackendDXContext->cStreamOutput; ++i)
6622 dxDestroyStreamOutput(&pBackendDXContext->paStreamOutput[i]);
6623 }
6624
6625 rc = dxCOTableRealloc((void **)&pBackendDXContext->paStreamOutput, &pBackendDXContext->cStreamOutput,
6626 sizeof(pBackendDXContext->paStreamOutput[0]), pDXContext->cot.cStreamOutput, cValidEntries);
6627 AssertRCBreak(rc);
6628
6629 for (uint32_t i = 0; i < cValidEntries; ++i)
6630 {
6631 SVGACOTableDXStreamOutputEntry const *pEntry = &pDXContext->cot.paStreamOutput[i];
6632 /** @todo The caller must verify the COTable content using same rules as when a new entry is defined. */
6633 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6634 continue; /* Skip uninitialized entry. */
6635
6636 dxDefineStreamOutput(pDXContext, i, pEntry);
6637 }
6638 break;
6639 case SVGA_COTABLE_DXQUERY:
6640 if (pBackendDXContext->papQuery)
6641 {
6642 for (uint32_t i = cValidEntries; i < pBackendDXContext->cQuery; ++i)
6643 D3D_RELEASE(pBackendDXContext->papQuery[i]);
6644 }
6645
6646 rc = dxCOTableRealloc((void **)&pBackendDXContext->papQuery, &pBackendDXContext->cQuery,
6647 sizeof(pBackendDXContext->papQuery[0]), pDXContext->cot.cQuery, cValidEntries);
6648 AssertRCBreak(rc);
6649
6650 for (uint32_t i = 0; i < cValidEntries; ++i)
6651 {
6652 SVGACOTableDXQueryEntry const *pEntry = &pDXContext->cot.paQuery[i];
6653 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6654 continue; /* Skip uninitialized entry. */
6655
6656 AssertFailed(); /** @todo implement */
6657 }
6658 break;
6659 case SVGA_COTABLE_DXSHADER:
6660 if (pBackendDXContext->paShader)
6661 {
6662 /* Destroy the no longer used entries. */
6663 for (uint32_t i = cValidEntries; i < pBackendDXContext->cShader; ++i)
6664 dxDestroyShader(&pBackendDXContext->paShader[i]);
6665 }
6666
6667 rc = dxCOTableRealloc((void **)&pBackendDXContext->paShader, &pBackendDXContext->cShader,
6668 sizeof(pBackendDXContext->paShader[0]), pDXContext->cot.cShader, cValidEntries);
6669 AssertRCBreak(rc);
6670
6671 for (uint32_t i = 0; i < cValidEntries; ++i)
6672 {
6673 SVGACOTableDXShaderEntry const *pEntry = &pDXContext->cot.paShader[i];
6674 /** @todo The caller must verify the COTable content using same rules as when a new entry is defined. */
6675 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6676 continue; /* Skip uninitialized entry. */
6677
6678 /** @todo this should be in the common DX code (the caller). */
6679 PVMSVGA3DSHADER pShader = &pDXContext->paShader[i];
6680 pShader->id = i;
6681 pShader->cid = pDXContext->cid;
6682 pShader->type = pEntry->type;
6683 pShader->cbData = pEntry->sizeInBytes;
6684 pShader->pShaderProgram = NULL;
6685 pShader->u.pvBackendShader = NULL;
6686
6687 dxDefineShader(pDXContext, i, pEntry);
6688 }
6689 break;
6690 case SVGA_COTABLE_UAVIEW:
6691 AssertFailed(); /** @todo Implement */
6692 break;
6693 case SVGA_COTABLE_MAX: break; /* Compiler warning */
6694 }
6695 return rc;
6696}
6697
6698
6699static DECLCALLBACK(int) vmsvga3dBackDXBufferCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6700{
6701 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6702
6703 RT_NOREF(pBackend, pDXContext);
6704 AssertFailed(); /** @todo Implement */
6705 return VERR_NOT_IMPLEMENTED;
6706}
6707
6708
6709static DECLCALLBACK(int) vmsvga3dBackDXSurfaceCopyAndReadback(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6710{
6711 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6712
6713 RT_NOREF(pBackend, pDXContext);
6714 AssertFailed(); /** @todo Implement */
6715 return VERR_NOT_IMPLEMENTED;
6716}
6717
6718
6719static DECLCALLBACK(int) vmsvga3dBackDXMoveQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6720{
6721 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6722
6723 RT_NOREF(pBackend, pDXContext);
6724 AssertFailed(); /** @todo Implement */
6725 return VERR_NOT_IMPLEMENTED;
6726}
6727
6728
6729static DECLCALLBACK(int) vmsvga3dBackDXBindAllQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6730{
6731 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6732
6733 RT_NOREF(pBackend, pDXContext);
6734 AssertFailed(); /** @todo Implement */
6735 return VERR_NOT_IMPLEMENTED;
6736}
6737
6738
6739static DECLCALLBACK(int) vmsvga3dBackDXReadbackAllQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6740{
6741 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6742
6743 RT_NOREF(pBackend, pDXContext);
6744 AssertFailed(); /** @todo Implement */
6745 return VERR_NOT_IMPLEMENTED;
6746}
6747
6748
6749static DECLCALLBACK(int) vmsvga3dBackDXMobFence64(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6750{
6751 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6752
6753 RT_NOREF(pBackend, pDXContext);
6754 AssertFailed(); /** @todo Implement */
6755 return VERR_NOT_IMPLEMENTED;
6756}
6757
6758
6759static DECLCALLBACK(int) vmsvga3dBackDXBindAllShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6760{
6761 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6762
6763 RT_NOREF(pBackend, pDXContext);
6764 AssertFailed(); /** @todo Implement */
6765 return VERR_NOT_IMPLEMENTED;
6766}
6767
6768
6769static DECLCALLBACK(int) vmsvga3dBackDXHint(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6770{
6771 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6772
6773 RT_NOREF(pBackend, pDXContext);
6774 AssertFailed(); /** @todo Implement */
6775 return VERR_NOT_IMPLEMENTED;
6776}
6777
6778
6779static DECLCALLBACK(int) vmsvga3dBackDXBufferUpdate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6780{
6781 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6782
6783 RT_NOREF(pBackend, pDXContext);
6784 AssertFailed(); /** @todo Implement */
6785 return VERR_NOT_IMPLEMENTED;
6786}
6787
6788
6789static DECLCALLBACK(int) vmsvga3dBackDXSetVSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6790{
6791 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6792
6793 RT_NOREF(pBackend, pDXContext);
6794 AssertFailed(); /** @todo Implement */
6795 return VERR_NOT_IMPLEMENTED;
6796}
6797
6798
6799static DECLCALLBACK(int) vmsvga3dBackDXSetPSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6800{
6801 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6802
6803 RT_NOREF(pBackend, pDXContext);
6804 AssertFailed(); /** @todo Implement */
6805 return VERR_NOT_IMPLEMENTED;
6806}
6807
6808
6809static DECLCALLBACK(int) vmsvga3dBackDXSetGSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6810{
6811 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6812
6813 RT_NOREF(pBackend, pDXContext);
6814 AssertFailed(); /** @todo Implement */
6815 return VERR_NOT_IMPLEMENTED;
6816}
6817
6818
6819static DECLCALLBACK(int) vmsvga3dBackDXSetHSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6820{
6821 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6822
6823 RT_NOREF(pBackend, pDXContext);
6824 AssertFailed(); /** @todo Implement */
6825 return VERR_NOT_IMPLEMENTED;
6826}
6827
6828
6829static DECLCALLBACK(int) vmsvga3dBackDXSetDSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6830{
6831 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6832
6833 RT_NOREF(pBackend, pDXContext);
6834 AssertFailed(); /** @todo Implement */
6835 return VERR_NOT_IMPLEMENTED;
6836}
6837
6838
6839static DECLCALLBACK(int) vmsvga3dBackDXSetCSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6840{
6841 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6842
6843 RT_NOREF(pBackend, pDXContext);
6844 AssertFailed(); /** @todo Implement */
6845 return VERR_NOT_IMPLEMENTED;
6846}
6847
6848
6849static DECLCALLBACK(int) vmsvga3dBackDXCondBindAllShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6850{
6851 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6852
6853 RT_NOREF(pBackend, pDXContext);
6854 AssertFailed(); /** @todo Implement */
6855 return VERR_NOT_IMPLEMENTED;
6856}
6857
6858
6859static DECLCALLBACK(int) vmsvga3dBackScreenCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6860{
6861 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6862
6863 RT_NOREF(pBackend, pDXContext);
6864 AssertFailed(); /** @todo Implement */
6865 return VERR_NOT_IMPLEMENTED;
6866}
6867
6868
6869static DECLCALLBACK(int) vmsvga3dBackGrowOTable(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6870{
6871 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6872
6873 RT_NOREF(pBackend, pDXContext);
6874 AssertFailed(); /** @todo Implement */
6875 return VERR_NOT_IMPLEMENTED;
6876}
6877
6878
6879static DECLCALLBACK(int) vmsvga3dBackDXGrowCOTable(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6880{
6881 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6882
6883 RT_NOREF(pBackend, pDXContext);
6884 AssertFailed(); /** @todo Implement */
6885 return VERR_NOT_IMPLEMENTED;
6886}
6887
6888
6889static DECLCALLBACK(int) vmsvga3dBackIntraSurfaceCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6890{
6891 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6892
6893 RT_NOREF(pBackend, pDXContext);
6894 AssertFailed(); /** @todo Implement */
6895 return VERR_NOT_IMPLEMENTED;
6896}
6897
6898
6899static DECLCALLBACK(int) vmsvga3dBackDefineGBSurface_v3(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6900{
6901 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6902
6903 RT_NOREF(pBackend, pDXContext);
6904 AssertFailed(); /** @todo Implement */
6905 return VERR_NOT_IMPLEMENTED;
6906}
6907
6908
6909static DECLCALLBACK(int) vmsvga3dBackDXResolveCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6910{
6911 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6912
6913 RT_NOREF(pBackend, pDXContext);
6914 AssertFailed(); /** @todo Implement */
6915 return VERR_NOT_IMPLEMENTED;
6916}
6917
6918
6919static DECLCALLBACK(int) vmsvga3dBackDXPredResolveCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6920{
6921 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6922
6923 RT_NOREF(pBackend, pDXContext);
6924 AssertFailed(); /** @todo Implement */
6925 return VERR_NOT_IMPLEMENTED;
6926}
6927
6928
6929static DECLCALLBACK(int) vmsvga3dBackDXPredConvertRegion(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6930{
6931 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6932
6933 RT_NOREF(pBackend, pDXContext);
6934 AssertFailed(); /** @todo Implement */
6935 return VERR_NOT_IMPLEMENTED;
6936}
6937
6938
6939static DECLCALLBACK(int) vmsvga3dBackDXPredConvert(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6940{
6941 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6942
6943 RT_NOREF(pBackend, pDXContext);
6944 AssertFailed(); /** @todo Implement */
6945 return VERR_NOT_IMPLEMENTED;
6946}
6947
6948
6949static DECLCALLBACK(int) vmsvga3dBackWholeSurfaceCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6950{
6951 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6952
6953 RT_NOREF(pBackend, pDXContext);
6954 AssertFailed(); /** @todo Implement */
6955 return VERR_NOT_IMPLEMENTED;
6956}
6957
6958
6959static DECLCALLBACK(int) vmsvga3dBackDXDefineUAView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6960{
6961 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6962
6963 RT_NOREF(pBackend, pDXContext);
6964 AssertFailed(); /** @todo Implement */
6965 return VERR_NOT_IMPLEMENTED;
6966}
6967
6968
6969static DECLCALLBACK(int) vmsvga3dBackDXDestroyUAView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6970{
6971 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6972
6973 RT_NOREF(pBackend, pDXContext);
6974 AssertFailed(); /** @todo Implement */
6975 return VERR_NOT_IMPLEMENTED;
6976}
6977
6978
6979static DECLCALLBACK(int) vmsvga3dBackDXClearUAViewUint(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6980{
6981 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6982
6983 RT_NOREF(pBackend, pDXContext);
6984 AssertFailed(); /** @todo Implement */
6985 return VERR_NOT_IMPLEMENTED;
6986}
6987
6988
6989static DECLCALLBACK(int) vmsvga3dBackDXClearUAViewFloat(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6990{
6991 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6992
6993 RT_NOREF(pBackend, pDXContext);
6994 AssertFailed(); /** @todo Implement */
6995 return VERR_NOT_IMPLEMENTED;
6996}
6997
6998
6999static DECLCALLBACK(int) vmsvga3dBackDXCopyStructureCount(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7000{
7001 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7002
7003 RT_NOREF(pBackend, pDXContext);
7004 AssertFailed(); /** @todo Implement */
7005 return VERR_NOT_IMPLEMENTED;
7006}
7007
7008
7009static DECLCALLBACK(int) vmsvga3dBackDXSetUAViews(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7010{
7011 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7012
7013 RT_NOREF(pBackend, pDXContext);
7014 AssertFailed(); /** @todo Implement */
7015 return VERR_NOT_IMPLEMENTED;
7016}
7017
7018
7019static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexedInstancedIndirect(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7020{
7021 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7022
7023 RT_NOREF(pBackend, pDXContext);
7024 AssertFailed(); /** @todo Implement */
7025 return VERR_NOT_IMPLEMENTED;
7026}
7027
7028
7029static DECLCALLBACK(int) vmsvga3dBackDXDrawInstancedIndirect(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7030{
7031 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7032
7033 RT_NOREF(pBackend, pDXContext);
7034 AssertFailed(); /** @todo Implement */
7035 return VERR_NOT_IMPLEMENTED;
7036}
7037
7038
7039static DECLCALLBACK(int) vmsvga3dBackDXDispatch(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7040{
7041 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7042
7043 RT_NOREF(pBackend, pDXContext);
7044 AssertFailed(); /** @todo Implement */
7045 return VERR_NOT_IMPLEMENTED;
7046}
7047
7048
7049static DECLCALLBACK(int) vmsvga3dBackDXDispatchIndirect(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7050{
7051 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7052
7053 RT_NOREF(pBackend, pDXContext);
7054 AssertFailed(); /** @todo Implement */
7055 return VERR_NOT_IMPLEMENTED;
7056}
7057
7058
7059static DECLCALLBACK(int) vmsvga3dBackWriteZeroSurface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7060{
7061 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7062
7063 RT_NOREF(pBackend, pDXContext);
7064 AssertFailed(); /** @todo Implement */
7065 return VERR_NOT_IMPLEMENTED;
7066}
7067
7068
7069static DECLCALLBACK(int) vmsvga3dBackHintZeroSurface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7070{
7071 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7072
7073 RT_NOREF(pBackend, pDXContext);
7074 AssertFailed(); /** @todo Implement */
7075 return VERR_NOT_IMPLEMENTED;
7076}
7077
7078
7079static DECLCALLBACK(int) vmsvga3dBackDXTransferToBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7080{
7081 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7082
7083 RT_NOREF(pBackend, pDXContext);
7084 AssertFailed(); /** @todo Implement */
7085 return VERR_NOT_IMPLEMENTED;
7086}
7087
7088
7089static DECLCALLBACK(int) vmsvga3dBackDXSetStructureCount(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7090{
7091 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7092
7093 RT_NOREF(pBackend, pDXContext);
7094 AssertFailed(); /** @todo Implement */
7095 return VERR_NOT_IMPLEMENTED;
7096}
7097
7098
7099static DECLCALLBACK(int) vmsvga3dBackLogicOpsBitBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7100{
7101 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7102
7103 RT_NOREF(pBackend, pDXContext);
7104 AssertFailed(); /** @todo Implement */
7105 return VERR_NOT_IMPLEMENTED;
7106}
7107
7108
7109static DECLCALLBACK(int) vmsvga3dBackLogicOpsTransBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7110{
7111 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7112
7113 RT_NOREF(pBackend, pDXContext);
7114 AssertFailed(); /** @todo Implement */
7115 return VERR_NOT_IMPLEMENTED;
7116}
7117
7118
7119static DECLCALLBACK(int) vmsvga3dBackLogicOpsStretchBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7120{
7121 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7122
7123 RT_NOREF(pBackend, pDXContext);
7124 AssertFailed(); /** @todo Implement */
7125 return VERR_NOT_IMPLEMENTED;
7126}
7127
7128
7129static DECLCALLBACK(int) vmsvga3dBackLogicOpsColorFill(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7130{
7131 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7132
7133 RT_NOREF(pBackend, pDXContext);
7134 AssertFailed(); /** @todo Implement */
7135 return VERR_NOT_IMPLEMENTED;
7136}
7137
7138
7139static DECLCALLBACK(int) vmsvga3dBackLogicOpsAlphaBlend(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7140{
7141 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7142
7143 RT_NOREF(pBackend, pDXContext);
7144 AssertFailed(); /** @todo Implement */
7145 return VERR_NOT_IMPLEMENTED;
7146}
7147
7148
7149static DECLCALLBACK(int) vmsvga3dBackLogicOpsClearTypeBlend(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7150{
7151 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7152
7153 RT_NOREF(pBackend, pDXContext);
7154 AssertFailed(); /** @todo Implement */
7155 return VERR_NOT_IMPLEMENTED;
7156}
7157
7158
7159static DECLCALLBACK(int) vmsvga3dBackDefineGBSurface_v4(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7160{
7161 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7162
7163 RT_NOREF(pBackend, pDXContext);
7164 AssertFailed(); /** @todo Implement */
7165 return VERR_NOT_IMPLEMENTED;
7166}
7167
7168
7169static DECLCALLBACK(int) vmsvga3dBackDXSetCSUAViews(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7170{
7171 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7172
7173 RT_NOREF(pBackend, pDXContext);
7174 AssertFailed(); /** @todo Implement */
7175 return VERR_NOT_IMPLEMENTED;
7176}
7177
7178
7179static DECLCALLBACK(int) vmsvga3dBackDXSetMinLOD(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7180{
7181 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7182
7183 RT_NOREF(pBackend, pDXContext);
7184 AssertFailed(); /** @todo Implement */
7185 return VERR_NOT_IMPLEMENTED;
7186}
7187
7188
7189static DECLCALLBACK(int) vmsvga3dBackDXDefineStreamOutputWithMob(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7190{
7191 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7192
7193 RT_NOREF(pBackend, pDXContext);
7194 AssertFailed(); /** @todo Implement */
7195 return VERR_NOT_IMPLEMENTED;
7196}
7197
7198
7199static DECLCALLBACK(int) vmsvga3dBackDXSetShaderIface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7200{
7201 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7202
7203 RT_NOREF(pBackend, pDXContext);
7204 AssertFailed(); /** @todo Implement */
7205 return VERR_NOT_IMPLEMENTED;
7206}
7207
7208
7209static DECLCALLBACK(int) vmsvga3dBackDXBindStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7210{
7211 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7212
7213 RT_NOREF(pBackend, pDXContext);
7214 AssertFailed(); /** @todo Implement */
7215 return VERR_NOT_IMPLEMENTED;
7216}
7217
7218
7219static DECLCALLBACK(int) vmsvga3dBackSurfaceStretchBltNonMSToMS(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7220{
7221 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7222
7223 RT_NOREF(pBackend, pDXContext);
7224 AssertFailed(); /** @todo Implement */
7225 return VERR_NOT_IMPLEMENTED;
7226}
7227
7228
7229static DECLCALLBACK(int) vmsvga3dBackDXBindShaderIface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7230{
7231 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7232
7233 RT_NOREF(pBackend, pDXContext);
7234 AssertFailed(); /** @todo Implement */
7235 return VERR_NOT_IMPLEMENTED;
7236}
7237
7238
7239static DECLCALLBACK(int) vmsvga3dBackQueryInterface(PVGASTATECC pThisCC, char const *pszInterfaceName, void *pvInterfaceFuncs, size_t cbInterfaceFuncs)
7240{
7241 RT_NOREF(pThisCC);
7242
7243 int rc = VINF_SUCCESS;
7244 if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_DX) == 0)
7245 {
7246 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSDX))
7247 {
7248 if (pvInterfaceFuncs)
7249 {
7250 VMSVGA3DBACKENDFUNCSDX *p = (VMSVGA3DBACKENDFUNCSDX *)pvInterfaceFuncs;
7251 p->pfnDXDefineContext = vmsvga3dBackDXDefineContext;
7252 p->pfnDXDestroyContext = vmsvga3dBackDXDestroyContext;
7253 p->pfnDXBindContext = vmsvga3dBackDXBindContext;
7254 p->pfnDXReadbackContext = vmsvga3dBackDXReadbackContext;
7255 p->pfnDXInvalidateContext = vmsvga3dBackDXInvalidateContext;
7256 p->pfnDXSetSingleConstantBuffer = vmsvga3dBackDXSetSingleConstantBuffer;
7257 p->pfnDXSetShaderResources = vmsvga3dBackDXSetShaderResources;
7258 p->pfnDXSetShader = vmsvga3dBackDXSetShader;
7259 p->pfnDXSetSamplers = vmsvga3dBackDXSetSamplers;
7260 p->pfnDXDraw = vmsvga3dBackDXDraw;
7261 p->pfnDXDrawIndexed = vmsvga3dBackDXDrawIndexed;
7262 p->pfnDXDrawInstanced = vmsvga3dBackDXDrawInstanced;
7263 p->pfnDXDrawIndexedInstanced = vmsvga3dBackDXDrawIndexedInstanced;
7264 p->pfnDXDrawAuto = vmsvga3dBackDXDrawAuto;
7265 p->pfnDXSetInputLayout = vmsvga3dBackDXSetInputLayout;
7266 p->pfnDXSetVertexBuffers = vmsvga3dBackDXSetVertexBuffers;
7267 p->pfnDXSetIndexBuffer = vmsvga3dBackDXSetIndexBuffer;
7268 p->pfnDXSetTopology = vmsvga3dBackDXSetTopology;
7269 p->pfnDXSetRenderTargets = vmsvga3dBackDXSetRenderTargets;
7270 p->pfnDXSetBlendState = vmsvga3dBackDXSetBlendState;
7271 p->pfnDXSetDepthStencilState = vmsvga3dBackDXSetDepthStencilState;
7272 p->pfnDXSetRasterizerState = vmsvga3dBackDXSetRasterizerState;
7273 p->pfnDXDefineQuery = vmsvga3dBackDXDefineQuery;
7274 p->pfnDXDestroyQuery = vmsvga3dBackDXDestroyQuery;
7275 p->pfnDXBindQuery = vmsvga3dBackDXBindQuery;
7276 p->pfnDXSetQueryOffset = vmsvga3dBackDXSetQueryOffset;
7277 p->pfnDXBeginQuery = vmsvga3dBackDXBeginQuery;
7278 p->pfnDXEndQuery = vmsvga3dBackDXEndQuery;
7279 p->pfnDXReadbackQuery = vmsvga3dBackDXReadbackQuery;
7280 p->pfnDXSetPredication = vmsvga3dBackDXSetPredication;
7281 p->pfnDXSetSOTargets = vmsvga3dBackDXSetSOTargets;
7282 p->pfnDXSetViewports = vmsvga3dBackDXSetViewports;
7283 p->pfnDXSetScissorRects = vmsvga3dBackDXSetScissorRects;
7284 p->pfnDXClearRenderTargetView = vmsvga3dBackDXClearRenderTargetView;
7285 p->pfnDXClearDepthStencilView = vmsvga3dBackDXClearDepthStencilView;
7286 p->pfnDXPredCopyRegion = vmsvga3dBackDXPredCopyRegion;
7287 p->pfnDXPredCopy = vmsvga3dBackDXPredCopy;
7288 p->pfnDXPresentBlt = vmsvga3dBackDXPresentBlt;
7289 p->pfnDXGenMips = vmsvga3dBackDXGenMips;
7290 p->pfnDXDefineShaderResourceView = vmsvga3dBackDXDefineShaderResourceView;
7291 p->pfnDXDestroyShaderResourceView = vmsvga3dBackDXDestroyShaderResourceView;
7292 p->pfnDXDefineRenderTargetView = vmsvga3dBackDXDefineRenderTargetView;
7293 p->pfnDXDestroyRenderTargetView = vmsvga3dBackDXDestroyRenderTargetView;
7294 p->pfnDXDefineDepthStencilView = vmsvga3dBackDXDefineDepthStencilView;
7295 p->pfnDXDestroyDepthStencilView = vmsvga3dBackDXDestroyDepthStencilView;
7296 p->pfnDXDefineElementLayout = vmsvga3dBackDXDefineElementLayout;
7297 p->pfnDXDestroyElementLayout = vmsvga3dBackDXDestroyElementLayout;
7298 p->pfnDXDefineBlendState = vmsvga3dBackDXDefineBlendState;
7299 p->pfnDXDestroyBlendState = vmsvga3dBackDXDestroyBlendState;
7300 p->pfnDXDefineDepthStencilState = vmsvga3dBackDXDefineDepthStencilState;
7301 p->pfnDXDestroyDepthStencilState = vmsvga3dBackDXDestroyDepthStencilState;
7302 p->pfnDXDefineRasterizerState = vmsvga3dBackDXDefineRasterizerState;
7303 p->pfnDXDestroyRasterizerState = vmsvga3dBackDXDestroyRasterizerState;
7304 p->pfnDXDefineSamplerState = vmsvga3dBackDXDefineSamplerState;
7305 p->pfnDXDestroySamplerState = vmsvga3dBackDXDestroySamplerState;
7306 p->pfnDXDefineShader = vmsvga3dBackDXDefineShader;
7307 p->pfnDXDestroyShader = vmsvga3dBackDXDestroyShader;
7308 p->pfnDXBindShader = vmsvga3dBackDXBindShader;
7309 p->pfnDXDefineStreamOutput = vmsvga3dBackDXDefineStreamOutput;
7310 p->pfnDXDestroyStreamOutput = vmsvga3dBackDXDestroyStreamOutput;
7311 p->pfnDXSetStreamOutput = vmsvga3dBackDXSetStreamOutput;
7312 p->pfnDXSetCOTable = vmsvga3dBackDXSetCOTable;
7313 p->pfnDXBufferCopy = vmsvga3dBackDXBufferCopy;
7314 p->pfnDXSurfaceCopyAndReadback = vmsvga3dBackDXSurfaceCopyAndReadback;
7315 p->pfnDXMoveQuery = vmsvga3dBackDXMoveQuery;
7316 p->pfnDXBindAllQuery = vmsvga3dBackDXBindAllQuery;
7317 p->pfnDXReadbackAllQuery = vmsvga3dBackDXReadbackAllQuery;
7318 p->pfnDXMobFence64 = vmsvga3dBackDXMobFence64;
7319 p->pfnDXBindAllShader = vmsvga3dBackDXBindAllShader;
7320 p->pfnDXHint = vmsvga3dBackDXHint;
7321 p->pfnDXBufferUpdate = vmsvga3dBackDXBufferUpdate;
7322 p->pfnDXSetVSConstantBufferOffset = vmsvga3dBackDXSetVSConstantBufferOffset;
7323 p->pfnDXSetPSConstantBufferOffset = vmsvga3dBackDXSetPSConstantBufferOffset;
7324 p->pfnDXSetGSConstantBufferOffset = vmsvga3dBackDXSetGSConstantBufferOffset;
7325 p->pfnDXSetHSConstantBufferOffset = vmsvga3dBackDXSetHSConstantBufferOffset;
7326 p->pfnDXSetDSConstantBufferOffset = vmsvga3dBackDXSetDSConstantBufferOffset;
7327 p->pfnDXSetCSConstantBufferOffset = vmsvga3dBackDXSetCSConstantBufferOffset;
7328 p->pfnDXCondBindAllShader = vmsvga3dBackDXCondBindAllShader;
7329 p->pfnScreenCopy = vmsvga3dBackScreenCopy;
7330 p->pfnGrowOTable = vmsvga3dBackGrowOTable;
7331 p->pfnDXGrowCOTable = vmsvga3dBackDXGrowCOTable;
7332 p->pfnIntraSurfaceCopy = vmsvga3dBackIntraSurfaceCopy;
7333 p->pfnDefineGBSurface_v3 = vmsvga3dBackDefineGBSurface_v3;
7334 p->pfnDXResolveCopy = vmsvga3dBackDXResolveCopy;
7335 p->pfnDXPredResolveCopy = vmsvga3dBackDXPredResolveCopy;
7336 p->pfnDXPredConvertRegion = vmsvga3dBackDXPredConvertRegion;
7337 p->pfnDXPredConvert = vmsvga3dBackDXPredConvert;
7338 p->pfnWholeSurfaceCopy = vmsvga3dBackWholeSurfaceCopy;
7339 p->pfnDXDefineUAView = vmsvga3dBackDXDefineUAView;
7340 p->pfnDXDestroyUAView = vmsvga3dBackDXDestroyUAView;
7341 p->pfnDXClearUAViewUint = vmsvga3dBackDXClearUAViewUint;
7342 p->pfnDXClearUAViewFloat = vmsvga3dBackDXClearUAViewFloat;
7343 p->pfnDXCopyStructureCount = vmsvga3dBackDXCopyStructureCount;
7344 p->pfnDXSetUAViews = vmsvga3dBackDXSetUAViews;
7345 p->pfnDXDrawIndexedInstancedIndirect = vmsvga3dBackDXDrawIndexedInstancedIndirect;
7346 p->pfnDXDrawInstancedIndirect = vmsvga3dBackDXDrawInstancedIndirect;
7347 p->pfnDXDispatch = vmsvga3dBackDXDispatch;
7348 p->pfnDXDispatchIndirect = vmsvga3dBackDXDispatchIndirect;
7349 p->pfnWriteZeroSurface = vmsvga3dBackWriteZeroSurface;
7350 p->pfnHintZeroSurface = vmsvga3dBackHintZeroSurface;
7351 p->pfnDXTransferToBuffer = vmsvga3dBackDXTransferToBuffer;
7352 p->pfnDXSetStructureCount = vmsvga3dBackDXSetStructureCount;
7353 p->pfnLogicOpsBitBlt = vmsvga3dBackLogicOpsBitBlt;
7354 p->pfnLogicOpsTransBlt = vmsvga3dBackLogicOpsTransBlt;
7355 p->pfnLogicOpsStretchBlt = vmsvga3dBackLogicOpsStretchBlt;
7356 p->pfnLogicOpsColorFill = vmsvga3dBackLogicOpsColorFill;
7357 p->pfnLogicOpsAlphaBlend = vmsvga3dBackLogicOpsAlphaBlend;
7358 p->pfnLogicOpsClearTypeBlend = vmsvga3dBackLogicOpsClearTypeBlend;
7359 p->pfnDefineGBSurface_v4 = vmsvga3dBackDefineGBSurface_v4;
7360 p->pfnDXSetCSUAViews = vmsvga3dBackDXSetCSUAViews;
7361 p->pfnDXSetMinLOD = vmsvga3dBackDXSetMinLOD;
7362 p->pfnDXDefineStreamOutputWithMob = vmsvga3dBackDXDefineStreamOutputWithMob;
7363 p->pfnDXSetShaderIface = vmsvga3dBackDXSetShaderIface;
7364 p->pfnDXBindStreamOutput = vmsvga3dBackDXBindStreamOutput;
7365 p->pfnSurfaceStretchBltNonMSToMS = vmsvga3dBackSurfaceStretchBltNonMSToMS;
7366 p->pfnDXBindShaderIface = vmsvga3dBackDXBindShaderIface;
7367 }
7368 }
7369 else
7370 {
7371 AssertFailed();
7372 rc = VERR_INVALID_PARAMETER;
7373 }
7374 }
7375 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_MAP) == 0)
7376 {
7377 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSMAP))
7378 {
7379 if (pvInterfaceFuncs)
7380 {
7381 VMSVGA3DBACKENDFUNCSMAP *p = (VMSVGA3DBACKENDFUNCSMAP *)pvInterfaceFuncs;
7382 p->pfnSurfaceMap = vmsvga3dBackSurfaceMap;
7383 p->pfnSurfaceUnmap = vmsvga3dBackSurfaceUnmap;
7384 }
7385 }
7386 else
7387 {
7388 AssertFailed();
7389 rc = VERR_INVALID_PARAMETER;
7390 }
7391 }
7392 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_GBO) == 0)
7393 {
7394 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSGBO))
7395 {
7396 if (pvInterfaceFuncs)
7397 {
7398 VMSVGA3DBACKENDFUNCSGBO *p = (VMSVGA3DBACKENDFUNCSGBO *)pvInterfaceFuncs;
7399 p->pfnScreenTargetBind = vmsvga3dScreenTargetBind;
7400 p->pfnScreenTargetUpdate = vmsvga3dScreenTargetUpdate;
7401 }
7402 }
7403 else
7404 {
7405 AssertFailed();
7406 rc = VERR_INVALID_PARAMETER;
7407 }
7408 }
7409 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_3D) == 0)
7410 {
7411 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCS3D))
7412 {
7413 if (pvInterfaceFuncs)
7414 {
7415 VMSVGA3DBACKENDFUNCS3D *p = (VMSVGA3DBACKENDFUNCS3D *)pvInterfaceFuncs;
7416 p->pfnInit = vmsvga3dBackInit;
7417 p->pfnPowerOn = vmsvga3dBackPowerOn;
7418 p->pfnTerminate = vmsvga3dBackTerminate;
7419 p->pfnReset = vmsvga3dBackReset;
7420 p->pfnQueryCaps = vmsvga3dBackQueryCaps;
7421 p->pfnChangeMode = vmsvga3dBackChangeMode;
7422 p->pfnCreateTexture = vmsvga3dBackCreateTexture;
7423 p->pfnSurfaceDestroy = vmsvga3dBackSurfaceDestroy;
7424 p->pfnSurfaceCopy = vmsvga3dBackSurfaceCopy;
7425 p->pfnSurfaceDMACopyBox = vmsvga3dBackSurfaceDMACopyBox;
7426 p->pfnSurfaceStretchBlt = vmsvga3dBackSurfaceStretchBlt;
7427 p->pfnUpdateHostScreenViewport = vmsvga3dBackUpdateHostScreenViewport;
7428 p->pfnDefineScreen = vmsvga3dBackDefineScreen;
7429 p->pfnDestroyScreen = vmsvga3dBackDestroyScreen;
7430 p->pfnSurfaceBlitToScreen = vmsvga3dBackSurfaceBlitToScreen;
7431 p->pfnSurfaceUpdateHeapBuffers = vmsvga3dBackSurfaceUpdateHeapBuffers;
7432 }
7433 }
7434 else
7435 {
7436 AssertFailed();
7437 rc = VERR_INVALID_PARAMETER;
7438 }
7439 }
7440 else
7441 rc = VERR_NOT_IMPLEMENTED;
7442 return rc;
7443}
7444
7445
7446extern VMSVGA3DBACKENDDESC const g_BackendDX =
7447{
7448 "DX",
7449 vmsvga3dBackQueryInterface
7450};
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette