VirtualBox

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

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

Devices/Graphics: parser; DrawIndexed for TRIANGLE_FAN; etc: bugref:9830

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