VirtualBox

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

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

Devices/Graphics/DevVGA-SVGA3d-win-dx.cpp: Some compile fixes on non Windows hosts, bugref:10013

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