VirtualBox

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

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

Devices/DevVGA-SVGA3d-win-dx: Fix possible call of RTMemFree(*ppvData) with uninitialized *ppvData

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 296.4 KB
Line 
1/* $Id: DevVGA-SVGA3d-win-dx.cpp 93739 2022-02-14 19:14: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 *ppvData = pvData;
5090 *pcbData = Bytes;
5091
5092 int rc = dxStagingBufferRealloc(pDevice, Bytes);
5093 if (RT_SUCCESS(rc))
5094 {
5095 /* Copy from the buffer to the staging buffer. */
5096 ID3D11Resource *pDstResource = pDevice->pStagingBuffer;
5097 UINT DstSubresource = 0;
5098 UINT DstX = Offset;
5099 UINT DstY = 0;
5100 UINT DstZ = 0;
5101 ID3D11Resource *pSrcResource = pBuffer;
5102 UINT SrcSubresource = 0;
5103 D3D11_BOX SrcBox;
5104 SrcBox.left = 0;
5105 SrcBox.top = 0;
5106 SrcBox.front = 0;
5107 SrcBox.right = Bytes;
5108 SrcBox.bottom = 1;
5109 SrcBox.back = 1;
5110 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
5111 pSrcResource, SrcSubresource, &SrcBox);
5112
5113 D3D11_MAPPED_SUBRESOURCE mappedResource;
5114 UINT const Subresource = 0; /* Buffers have only one subresource. */
5115 HRESULT hr = pDevice->pImmediateContext->Map(pDevice->pStagingBuffer, Subresource,
5116 D3D11_MAP_READ, /* MapFlags = */ 0, &mappedResource);
5117 if (SUCCEEDED(hr))
5118 {
5119 memcpy(pvData, mappedResource.pData, Bytes);
5120
5121 /* Unmap the staging buffer. */
5122 pDevice->pImmediateContext->Unmap(pDevice->pStagingBuffer, Subresource);
5123 }
5124 else
5125 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
5126
5127 }
5128
5129 if (RT_FAILURE(rc))
5130 {
5131 RTMemFree(*ppvData);
5132 *ppvData = NULL;
5133 *pcbData = 0;
5134 }
5135
5136 return rc;
5137}
5138
5139
5140static int dxDrawIndexedTriangleFan(DXDEVICE *pDevice, uint32_t IndexCountTF, uint32_t StartIndexLocationTF, int32_t BaseVertexLocationTF)
5141{
5142 /*
5143 * Emulate an indexed SVGA3D_PRIMITIVE_TRIANGLEFAN using an indexed draw of triangle list.
5144 */
5145
5146 /* Make sure that 16 bit indices are enough. 20000 ~= 65536 / 3 */
5147 AssertReturn(IndexCountTF <= 20000, VERR_NOT_SUPPORTED);
5148
5149 /* Save the current index buffer. */
5150 ID3D11Buffer *pSavedIndexBuffer = 0;
5151 DXGI_FORMAT SavedFormat = DXGI_FORMAT_UNKNOWN;
5152 UINT SavedOffset = 0;
5153 pDevice->pImmediateContext->IAGetIndexBuffer(&pSavedIndexBuffer, &SavedFormat, &SavedOffset);
5154
5155 AssertReturn( SavedFormat == DXGI_FORMAT_R16_UINT
5156 || SavedFormat == DXGI_FORMAT_R32_UINT, VERR_NOT_SUPPORTED);
5157
5158 /* How many bytes are used by triangle fan indices. */
5159 UINT const BytesPerIndexTF = SavedFormat == DXGI_FORMAT_R16_UINT ? 2 : 4;
5160 UINT const BytesTF = BytesPerIndexTF * IndexCountTF;
5161
5162 /* Read the current index buffer content to obtain indices. */
5163 void *pvDataTF;
5164 uint32_t cbDataTF;
5165 int rc = dxReadBuffer(pDevice, pSavedIndexBuffer, StartIndexLocationTF, BytesTF, &pvDataTF, &cbDataTF);
5166 AssertRCReturn(rc, rc);
5167 AssertReturnStmt(cbDataTF >= BytesPerIndexTF, RTMemFree(pvDataTF), VERR_INVALID_STATE);
5168
5169 /* Generate indices for triangle list. */
5170 UINT const IndexCount = 3 * (IndexCountTF - 2); /* 3_per_triangle * num_triangles */
5171 UINT const cbAlloc = IndexCount * sizeof(USHORT);
5172 USHORT *paIndices = (USHORT *)RTMemAlloc(cbAlloc);
5173 AssertReturnStmt(paIndices, RTMemFree(pvDataTF), VERR_NO_MEMORY);
5174
5175 USHORT iVertex = 1;
5176 if (BytesPerIndexTF == 2)
5177 {
5178 USHORT *paIndicesTF = (USHORT *)pvDataTF;
5179 for (UINT i = 0; i < IndexCount; i+= 3)
5180 {
5181 paIndices[i] = paIndicesTF[0];
5182 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5183 paIndices[i + 1] = paIndicesTF[iVertex];
5184 ++iVertex;
5185 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5186 paIndices[i + 2] = paIndicesTF[iVertex];
5187 }
5188 }
5189 else
5190 {
5191 UINT *paIndicesTF = (UINT *)pvDataTF;
5192 for (UINT i = 0; i < IndexCount; i+= 3)
5193 {
5194 paIndices[i] = paIndicesTF[0];
5195 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5196 paIndices[i + 1] = paIndicesTF[iVertex];
5197 ++iVertex;
5198 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5199 paIndices[i + 2] = paIndicesTF[iVertex];
5200 }
5201 }
5202
5203 D3D11_SUBRESOURCE_DATA InitData;
5204 InitData.pSysMem = paIndices;
5205 InitData.SysMemPitch = cbAlloc;
5206 InitData.SysMemSlicePitch = cbAlloc;
5207
5208 D3D11_BUFFER_DESC bd;
5209 RT_ZERO(bd);
5210 bd.ByteWidth = cbAlloc;
5211 bd.Usage = D3D11_USAGE_IMMUTABLE;
5212 bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
5213 //bd.CPUAccessFlags = 0;
5214 //bd.MiscFlags = 0;
5215 //bd.StructureByteStride = 0;
5216
5217 ID3D11Buffer *pIndexBuffer = 0;
5218 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, &InitData, &pIndexBuffer);
5219 Assert(SUCCEEDED(hr));RT_NOREF(hr);
5220
5221 /* Set up the device state. */
5222 pDevice->pImmediateContext->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
5223 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5224
5225 UINT const StartIndexLocation = 0;
5226 INT const BaseVertexLocation = BaseVertexLocationTF;
5227 pDevice->pImmediateContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation);
5228
5229 /* Restore the device state. */
5230 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
5231 pDevice->pImmediateContext->IASetIndexBuffer(pSavedIndexBuffer, SavedFormat, SavedOffset);
5232 D3D_RELEASE(pSavedIndexBuffer);
5233
5234 /* Cleanup. */
5235 D3D_RELEASE(pIndexBuffer);
5236 RTMemFree(paIndices);
5237 RTMemFree(pvDataTF);
5238
5239 return VINF_SUCCESS;
5240}
5241
5242
5243static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexed(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t indexCount, uint32_t startIndexLocation, int32_t baseVertexLocation)
5244{
5245 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5246 RT_NOREF(pBackend);
5247
5248 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5249 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5250
5251 dxSetupPipeline(pThisCC, pDXContext);
5252
5253 if (pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN)
5254 pDevice->pImmediateContext->DrawIndexed(indexCount, startIndexLocation, baseVertexLocation);
5255 else
5256 {
5257 dxDrawIndexedTriangleFan(pDevice, indexCount, startIndexLocation, baseVertexLocation);
5258 }
5259
5260 /* Note which surfaces are being drawn. */
5261 dxTrackRenderTargets(pThisCC, pDXContext);
5262
5263 return VINF_SUCCESS;
5264}
5265
5266
5267static DECLCALLBACK(int) vmsvga3dBackDXDrawInstanced(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
5268 uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation)
5269{
5270 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5271 RT_NOREF(pBackend);
5272
5273 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5274 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5275
5276 dxSetupPipeline(pThisCC, pDXContext);
5277
5278 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
5279
5280 pDevice->pImmediateContext->DrawInstanced(vertexCountPerInstance, instanceCount, startVertexLocation, startInstanceLocation);
5281
5282 /* Note which surfaces are being drawn. */
5283 dxTrackRenderTargets(pThisCC, pDXContext);
5284
5285 return VINF_SUCCESS;
5286}
5287
5288
5289static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexedInstanced(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
5290 uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation)
5291{
5292 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5293 RT_NOREF(pBackend);
5294
5295 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5296 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5297
5298 dxSetupPipeline(pThisCC, pDXContext);
5299
5300 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
5301
5302 pDevice->pImmediateContext->DrawIndexedInstanced(indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation);
5303
5304 /* Note which surfaces are being drawn. */
5305 dxTrackRenderTargets(pThisCC, pDXContext);
5306
5307 return VINF_SUCCESS;
5308}
5309
5310
5311static DECLCALLBACK(int) vmsvga3dBackDXDrawAuto(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5312{
5313 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
5314 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5315
5316 dxSetupPipeline(pThisCC, pDXContext);
5317
5318 RT_NOREF(pBackend, pDXContext);
5319 AssertFailed(); /** @todo Implement */
5320 return VERR_NOT_IMPLEMENTED;
5321}
5322
5323
5324static DECLCALLBACK(int) vmsvga3dBackDXSetInputLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId)
5325{
5326 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5327 RT_NOREF(pBackend);
5328
5329 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5330 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5331
5332 pDXContext->svgaDXContext.inputAssembly.layoutId = elementLayoutId;
5333
5334 DXELEMENTLAYOUT *pDXElementLayout = &pDXContext->pBackendDXContext->paElementLayout[elementLayoutId];
5335 if (!pDXElementLayout->pElementLayout)
5336 {
5337 uint32_t const idxShaderState = SVGA3D_SHADERTYPE_VS - SVGA3D_SHADERTYPE_MIN;
5338 uint32_t const shid = pDXContext->svgaDXContext.shaderState[idxShaderState].shaderId;
5339 AssertReturnStmt(shid < pDXContext->pBackendDXContext->cShader,
5340 LogRelMax(16, ("VMSVGA: DX shader is not set in DXSetInputLayout: shid = 0x%x\n", shid)),
5341 VERR_INVALID_STATE);
5342 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shid];
5343 AssertReturnStmt(pDXShader->pvDXBC,
5344 LogRelMax(16, ("VMSVGA: DX shader bytecode is not available in DXSetInputLayout: shid = %u\n", shid)),
5345 VERR_INVALID_STATE);
5346 HRESULT hr = pDevice->pDevice->CreateInputLayout(pDXElementLayout->aElementDesc,
5347 pDXElementLayout->cElementDesc,
5348 pDXShader->pvDXBC,
5349 pDXShader->cbDXBC,
5350 &pDXElementLayout->pElementLayout);
5351 AssertReturn(SUCCEEDED(hr), VERR_NO_MEMORY);
5352 }
5353
5354 pDevice->pImmediateContext->IASetInputLayout(pDXElementLayout->pElementLayout);
5355 return VINF_SUCCESS;
5356}
5357
5358
5359static DECLCALLBACK(int) vmsvga3dBackDXSetVertexBuffers(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t startBuffer, uint32_t cVertexBuffer, SVGA3dVertexBuffer const *paVertexBuffer)
5360{
5361 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5362 RT_NOREF(pBackend);
5363
5364 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5365 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5366
5367 /* For each paVertexBuffer[i]:
5368 * If the vertex buffer object does not exist then create it.
5369 * If the surface has been updated by the guest then update the buffer object.
5370 * Use IASetVertexBuffers to set the buffers.
5371 */
5372
5373 ID3D11Buffer *paResources[SVGA3D_DX_MAX_VERTEXBUFFERS];
5374 UINT paStride[SVGA3D_DX_MAX_VERTEXBUFFERS];
5375 UINT paOffset[SVGA3D_DX_MAX_VERTEXBUFFERS];
5376
5377 for (uint32_t i = 0; i < cVertexBuffer; ++i)
5378 {
5379 uint32_t const idxVertexBuffer = startBuffer + i;
5380
5381 /* Get corresponding resource. Create the buffer if does not yet exist. */
5382 if (paVertexBuffer[i].sid != SVGA_ID_INVALID)
5383 {
5384 PVMSVGA3DSURFACE pSurface;
5385 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, paVertexBuffer[i].sid, &pSurface);
5386 AssertRCReturn(rc, rc);
5387
5388 if (pSurface->pBackendSurface == NULL)
5389 {
5390 /* Create the resource and initialize it with the current surface data. */
5391 rc = vmsvga3dBackSurfaceCreateBuffer(pThisCC, pDXContext, pSurface);
5392 AssertRCReturn(rc, rc);
5393 }
5394#if 0
5395 if (pSurface->fDirty)
5396 {
5397 /* Get mobid for the surface and read from the MOB. */
5398 SVGA3dSurfaceImageId imageId;
5399 imageId.sid = paVertexBuffer[i].sid;
5400 imageId.face = 0;
5401 imageId.mipmap = 0;
5402
5403 SVGA3dBox box;
5404 box.x = 0;
5405 box.y = 0;
5406 box.z = 0;
5407 box.w = pSurface->paMipmapLevels[0].mipmapSize.width;
5408 box.h = 1;
5409 box.d = 1;
5410
5411 rc = vmsvgaR3UpdateGBSurface(pThisCC, &imageId, &box);
5412 AssertRCReturn(rc, rc);
5413 }
5414#endif
5415
5416 Assert(pSurface->pBackendSurface->u.pBuffer);
5417 paResources[idxVertexBuffer] = pSurface->pBackendSurface->u.pBuffer;
5418 paStride[idxVertexBuffer] = paVertexBuffer[i].stride;
5419 paOffset[idxVertexBuffer] = paVertexBuffer[i].offset;
5420 }
5421 else
5422 {
5423 paResources[idxVertexBuffer] = NULL;
5424 paStride[idxVertexBuffer] = 0;
5425 paOffset[idxVertexBuffer] = 0;
5426 }
5427
5428 pDXContext->svgaDXContext.inputAssembly.vertexBuffers[idxVertexBuffer].bufferId = paVertexBuffer[i].sid;
5429 pDXContext->svgaDXContext.inputAssembly.vertexBuffers[idxVertexBuffer].stride = paVertexBuffer[i].stride;
5430 pDXContext->svgaDXContext.inputAssembly.vertexBuffers[idxVertexBuffer].offset = paVertexBuffer[i].offset;
5431 }
5432
5433 pDevice->pImmediateContext->IASetVertexBuffers(startBuffer, cVertexBuffer,
5434 &paResources[startBuffer], &paStride[startBuffer], &paOffset[startBuffer]);
5435
5436 return VINF_SUCCESS;
5437}
5438
5439
5440static DECLCALLBACK(int) vmsvga3dBackDXSetIndexBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSurfaceId sid, SVGA3dSurfaceFormat format, uint32_t offset)
5441{
5442 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5443 RT_NOREF(pBackend);
5444
5445 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5446 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5447
5448 /* Get corresponding resource. Create the buffer if does not yet exist. */
5449 ID3D11Buffer *pResource;
5450 DXGI_FORMAT enmDxgiFormat;
5451
5452 if (sid != SVGA_ID_INVALID)
5453 {
5454 PVMSVGA3DSURFACE pSurface;
5455 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
5456 AssertRCReturn(rc, rc);
5457
5458 if (pSurface->pBackendSurface == NULL)
5459 {
5460 /* Create the resource and initialize it with the current surface data. */
5461 rc = vmsvga3dBackSurfaceCreateBuffer(pThisCC, pDXContext, pSurface);
5462 AssertRCReturn(rc, rc);
5463 }
5464#if 0
5465 if (pSurface->fDirty)
5466 {
5467 /* Get mobid for the surface and read from the MOB. */
5468 SVGA3dSurfaceImageId imageId;
5469 imageId.sid = sid;
5470 imageId.face = 0;
5471 imageId.mipmap = 0;
5472
5473 SVGA3dBox box;
5474 box.x = 0;
5475 box.y = 0;
5476 box.z = 0;
5477 box.w = pSurface->paMipmapLevels[0].mipmapSize.width;
5478 box.h = 1;
5479 box.d = 1;
5480
5481 rc = vmsvgaR3UpdateGBSurface(pThisCC, &imageId, &box);
5482 AssertRCReturn(rc, rc);
5483 }
5484#endif
5485 pResource = pSurface->pBackendSurface->u.pBuffer;
5486 enmDxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(format);
5487 AssertReturn(enmDxgiFormat == DXGI_FORMAT_R16_UINT || enmDxgiFormat == DXGI_FORMAT_R32_UINT, VERR_INVALID_PARAMETER);
5488 }
5489 else
5490 {
5491 pResource = NULL;
5492 enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
5493 }
5494
5495 pDevice->pImmediateContext->IASetIndexBuffer(pResource, enmDxgiFormat, offset);
5496 return VINF_SUCCESS;
5497}
5498
5499static D3D11_PRIMITIVE_TOPOLOGY dxTopology(SVGA3dPrimitiveType primitiveType)
5500{
5501 static D3D11_PRIMITIVE_TOPOLOGY const aD3D11PrimitiveTopology[SVGA3D_PRIMITIVE_MAX] =
5502 {
5503 D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED,
5504 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
5505 D3D11_PRIMITIVE_TOPOLOGY_POINTLIST,
5506 D3D11_PRIMITIVE_TOPOLOGY_LINELIST,
5507 D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP,
5508 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
5509 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, /* SVGA3D_PRIMITIVE_TRIANGLEFAN: No FAN in D3D11. */
5510 D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ,
5511 D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ,
5512 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ,
5513 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ,
5514 D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST,
5515 D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST,
5516 D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST,
5517 D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST,
5518 D3D11_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST,
5519 D3D11_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST,
5520 D3D11_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST,
5521 D3D11_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST,
5522 D3D11_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST,
5523 D3D11_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST,
5524 D3D11_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST,
5525 D3D11_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST,
5526 D3D11_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST,
5527 D3D11_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST,
5528 D3D11_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST,
5529 D3D11_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST,
5530 D3D11_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST,
5531 D3D11_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST,
5532 D3D11_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST,
5533 D3D11_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST,
5534 D3D11_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST,
5535 D3D11_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST,
5536 D3D11_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST,
5537 D3D11_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST,
5538 D3D11_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST,
5539 D3D11_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST,
5540 D3D11_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST,
5541 D3D11_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST,
5542 D3D11_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST,
5543 D3D11_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST,
5544 D3D11_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST,
5545 D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST,
5546 };
5547 return aD3D11PrimitiveTopology[primitiveType];
5548}
5549
5550static DECLCALLBACK(int) vmsvga3dBackDXSetTopology(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dPrimitiveType topology)
5551{
5552 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5553 RT_NOREF(pBackend);
5554
5555 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5556 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5557
5558 D3D11_PRIMITIVE_TOPOLOGY const enmTopology = dxTopology(topology);
5559 pDevice->pImmediateContext->IASetPrimitiveTopology(enmTopology);
5560 return VINF_SUCCESS;
5561}
5562
5563
5564static DECLCALLBACK(int) vmsvga3dBackDXSetRenderTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, uint32_t cRenderTargetViewId, SVGA3dRenderTargetViewId const *paRenderTargetViewId)
5565{
5566 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5567 RT_NOREF(pBackend);
5568
5569 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5570 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5571
5572 ID3D11RenderTargetView *papRenderTargetViews[SVGA3D_MAX_RENDER_TARGETS];
5573 RT_ZERO(papRenderTargetViews);
5574 for (uint32_t i = 0; i < cRenderTargetViewId; ++i)
5575 {
5576 SVGA3dRenderTargetViewId const renderTargetViewId = paRenderTargetViewId[i];
5577 if (renderTargetViewId != SVGA3D_INVALID_ID)
5578 {
5579 ASSERT_GUEST_RETURN(renderTargetViewId < pDXContext->pBackendDXContext->cRenderTargetView, VERR_INVALID_PARAMETER);
5580 papRenderTargetViews[i] = pDXContext->pBackendDXContext->papRenderTargetView[renderTargetViewId];
5581 }
5582 }
5583
5584 ID3D11DepthStencilView *pDepthStencilView;
5585 if (depthStencilViewId != SVGA_ID_INVALID)
5586 pDepthStencilView = pDXContext->pBackendDXContext->papDepthStencilView[depthStencilViewId];
5587 else
5588 pDepthStencilView = NULL;
5589
5590#ifdef DX_DEFERRED_SET_RENDER_TARGETS
5591 memcpy(pDXContext->pBackendDXContext->state.papRenderTargetViews, papRenderTargetViews, sizeof(papRenderTargetViews));
5592 pDXContext->pBackendDXContext->state.cRenderTargetViews = cRenderTargetViewId;
5593 pDXContext->pBackendDXContext->state.pDepthStencilView = pDepthStencilView;
5594 pDevice->pImmediateContext->OMSetRenderTargets(0, NULL, NULL);
5595#else
5596 pDevice->pImmediateContext->OMSetRenderTargets(cRenderTargetViewId, papRenderTargetViews, pDepthStencilView);
5597#endif
5598 return VINF_SUCCESS;
5599}
5600
5601
5602static DECLCALLBACK(int) vmsvga3dBackDXSetBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dBlendStateId blendId, float const blendFactor[4], uint32_t sampleMask)
5603{
5604 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5605 RT_NOREF(pBackend);
5606
5607 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5608 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5609
5610 ID3D11BlendState *pBlendState = pDXContext->pBackendDXContext->papBlendState[blendId];
5611 pDevice->pImmediateContext->OMSetBlendState(pBlendState, blendFactor, sampleMask);
5612
5613 pDXContext->svgaDXContext.renderState.blendStateId = blendId;
5614 pDXContext->svgaDXContext.renderState.blendFactor[0] = blendFactor[0];
5615 pDXContext->svgaDXContext.renderState.blendFactor[1] = blendFactor[1];
5616 pDXContext->svgaDXContext.renderState.blendFactor[2] = blendFactor[2];
5617 pDXContext->svgaDXContext.renderState.blendFactor[3] = blendFactor[3];
5618 pDXContext->svgaDXContext.renderState.sampleMask = sampleMask;
5619
5620 return VINF_SUCCESS;
5621}
5622
5623
5624static DECLCALLBACK(int) vmsvga3dBackDXSetDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId, uint32_t stencilRef)
5625{
5626 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5627 RT_NOREF(pBackend);
5628
5629 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5630 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5631
5632 ID3D11DepthStencilState *pDepthStencilState = pDXContext->pBackendDXContext->papDepthStencilState[depthStencilId];
5633 pDevice->pImmediateContext->OMSetDepthStencilState(pDepthStencilState, stencilRef);
5634
5635 pDXContext->svgaDXContext.renderState.depthStencilStateId = depthStencilId;
5636 pDXContext->svgaDXContext.renderState.stencilRef = stencilRef;
5637
5638 return VINF_SUCCESS;
5639}
5640
5641
5642static DECLCALLBACK(int) vmsvga3dBackDXSetRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId)
5643{
5644 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5645 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5646 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5647
5648 RT_NOREF(pBackend);
5649
5650 pDevice->pImmediateContext->RSSetState(pDXContext->pBackendDXContext->papRasterizerState[rasterizerId]);
5651 return VINF_SUCCESS;
5652}
5653
5654
5655static DECLCALLBACK(int) vmsvga3dBackDXDefineQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5656{
5657 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5658
5659 RT_NOREF(pBackend, pDXContext);
5660 AssertFailed(); /** @todo Implement */
5661 return VERR_NOT_IMPLEMENTED;
5662}
5663
5664
5665static DECLCALLBACK(int) vmsvga3dBackDXDestroyQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5666{
5667 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5668
5669 RT_NOREF(pBackend, pDXContext);
5670 AssertFailed(); /** @todo Implement */
5671 return VERR_NOT_IMPLEMENTED;
5672}
5673
5674
5675static DECLCALLBACK(int) vmsvga3dBackDXBindQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5676{
5677 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5678
5679 RT_NOREF(pBackend, pDXContext);
5680 AssertFailed(); /** @todo Implement */
5681 return VERR_NOT_IMPLEMENTED;
5682}
5683
5684
5685static DECLCALLBACK(int) vmsvga3dBackDXSetQueryOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5686{
5687 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5688
5689 RT_NOREF(pBackend, pDXContext);
5690 AssertFailed(); /** @todo Implement */
5691 return VERR_NOT_IMPLEMENTED;
5692}
5693
5694
5695static DECLCALLBACK(int) vmsvga3dBackDXBeginQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5696{
5697 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5698
5699 RT_NOREF(pBackend, pDXContext);
5700 AssertFailed(); /** @todo Implement */
5701 return VERR_NOT_IMPLEMENTED;
5702}
5703
5704
5705static DECLCALLBACK(int) vmsvga3dBackDXEndQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5706{
5707 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5708
5709 RT_NOREF(pBackend, pDXContext);
5710 AssertFailed(); /** @todo Implement */
5711 return VERR_NOT_IMPLEMENTED;
5712}
5713
5714
5715static DECLCALLBACK(int) vmsvga3dBackDXReadbackQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5716{
5717 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5718
5719 RT_NOREF(pBackend, pDXContext);
5720 AssertFailed(); /** @todo Implement */
5721 return VERR_NOT_IMPLEMENTED;
5722}
5723
5724
5725static DECLCALLBACK(int) vmsvga3dBackDXSetPredication(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5726{
5727 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5728
5729 RT_NOREF(pBackend, pDXContext);
5730 AssertFailed(); /** @todo Implement */
5731 return VERR_NOT_IMPLEMENTED;
5732}
5733
5734
5735static DECLCALLBACK(int) vmsvga3dBackDXSetSOTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t cSOTarget, SVGA3dSoTarget const *paSoTarget)
5736{
5737 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5738 RT_NOREF(pBackend);
5739
5740 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5741 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5742
5743 /* For each paSoTarget[i]:
5744 * If the stream outout buffer object does not exist then create it.
5745 * If the surface has been updated by the guest then update the buffer object.
5746 * Use SOSetTargets to set the buffers.
5747 */
5748
5749 ID3D11Buffer *paResource[SVGA3D_DX_MAX_SOTARGETS];
5750 UINT paOffset[SVGA3D_DX_MAX_SOTARGETS];
5751
5752 /* Always re-bind all 4 SO targets. They can be NULL. */
5753 for (uint32_t i = 0; i < SVGA3D_DX_MAX_SOTARGETS; ++i)
5754 {
5755 /* Get corresponding resource. Create the buffer if does not yet exist. */
5756 if (i < cSOTarget && paSoTarget[i].sid != SVGA_ID_INVALID)
5757 {
5758 PVMSVGA3DSURFACE pSurface;
5759 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, paSoTarget[i].sid, &pSurface);
5760 AssertRCReturn(rc, rc);
5761
5762 if (pSurface->pBackendSurface == NULL)
5763 {
5764 /* Create the resource. */
5765 rc = vmsvga3dBackSurfaceCreateSoBuffer(pThisCC, pDXContext, pSurface);
5766 AssertRCReturn(rc, rc);
5767 }
5768
5769 /** @todo How paSoTarget[i].sizeInBytes is used? Maybe when the buffer is created? */
5770 paResource[i] = pSurface->pBackendSurface->u.pBuffer;
5771 paOffset[i] = paSoTarget[i].offset;
5772
5773 /** @todo This should be in the caller. */
5774 pDXContext->svgaDXContext.streamOut.targets[i] = paSoTarget[i].sid;
5775 }
5776 else
5777 {
5778 paResource[i] = NULL;
5779 paOffset[i] = 0;
5780
5781 /** @todo This should be in the caller. */
5782 pDXContext->svgaDXContext.streamOut.targets[i] = SVGA_ID_INVALID;
5783 }
5784 }
5785
5786 pDevice->pImmediateContext->SOSetTargets(SVGA3D_DX_MAX_SOTARGETS, paResource, paOffset);
5787
5788 pDXContext->pBackendDXContext->cSOTarget = cSOTarget;
5789
5790 return VINF_SUCCESS;
5791}
5792
5793
5794static DECLCALLBACK(int) vmsvga3dBackDXSetViewports(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t cViewport, SVGA3dViewport const *paViewport)
5795{
5796 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5797 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5798 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5799
5800 RT_NOREF(pBackend);
5801
5802 /* D3D11_VIEWPORT is identical to SVGA3dViewport. */
5803 D3D11_VIEWPORT *pViewports = (D3D11_VIEWPORT *)paViewport;
5804
5805 pDevice->pImmediateContext->RSSetViewports(cViewport, pViewports);
5806 return VINF_SUCCESS;
5807}
5808
5809
5810static DECLCALLBACK(int) vmsvga3dBackDXSetScissorRects(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t cRect, SVGASignedRect const *paRect)
5811{
5812 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5813 RT_NOREF(pBackend);
5814
5815 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5816 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5817
5818 /* D3D11_RECT is identical to SVGASignedRect. */
5819 D3D11_RECT *pRects = (D3D11_RECT *)paRect;
5820
5821 pDevice->pImmediateContext->RSSetScissorRects(cRect, pRects);
5822 return VINF_SUCCESS;
5823}
5824
5825
5826static DECLCALLBACK(int) vmsvga3dBackDXClearRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGA3dRGBAFloat const *pRGBA)
5827{
5828 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5829 RT_NOREF(pBackend);
5830
5831 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5832 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5833
5834 ID3D11RenderTargetView *pRenderTargetView = pDXContext->pBackendDXContext->papRenderTargetView[renderTargetViewId];
5835 AssertReturn(pRenderTargetView, VERR_INVALID_STATE);
5836 pDevice->pImmediateContext->ClearRenderTargetView(pRenderTargetView, pRGBA->value);
5837 return VINF_SUCCESS;
5838}
5839
5840
5841static DECLCALLBACK(int) vmsvga3dBackDXClearDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t flags, SVGA3dDepthStencilViewId depthStencilViewId, float depth, uint8_t stencil)
5842{
5843 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5844 RT_NOREF(pBackend);
5845
5846 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5847 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5848
5849 ID3D11DepthStencilView *pDepthStencilView = pDXContext->pBackendDXContext->papDepthStencilView[depthStencilViewId];
5850 AssertReturn(pDepthStencilView, VERR_INVALID_STATE);
5851 pDevice->pImmediateContext->ClearDepthStencilView(pDepthStencilView, flags, depth, stencil);
5852 return VINF_SUCCESS;
5853}
5854
5855
5856static DECLCALLBACK(int) vmsvga3dBackDXPredCopyRegion(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSurfaceId dstSid, uint32_t dstSubResource, SVGA3dSurfaceId srcSid, uint32_t srcSubResource, SVGA3dCopyBox const *pBox)
5857{
5858 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5859 RT_NOREF(pBackend);
5860
5861 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5862 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5863
5864 PVMSVGA3DSURFACE pSrcSurface;
5865 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, srcSid, &pSrcSurface);
5866 AssertRCReturn(rc, rc);
5867
5868 PVMSVGA3DSURFACE pDstSurface;
5869 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, dstSid, &pDstSurface);
5870 AssertRCReturn(rc, rc);
5871
5872 if (pSrcSurface->pBackendSurface == NULL)
5873 {
5874 /* Create the resource. */
5875 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSrcSurface);
5876 AssertRCReturn(rc, rc);
5877 }
5878
5879 if (pDstSurface->pBackendSurface == NULL)
5880 {
5881 /* Create the resource. */
5882 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pDstSurface);
5883 AssertRCReturn(rc, rc);
5884 }
5885
5886 LogFunc(("cid %d: src cid %d%s -> dst cid %d%s\n",
5887 pDXContext->cid, pSrcSurface->idAssociatedContext,
5888 (pSrcSurface->surfaceFlags & SVGA3D_SURFACE_SCREENTARGET) ? " st" : "",
5889 pDstSurface->idAssociatedContext,
5890 (pDstSurface->surfaceFlags & SVGA3D_SURFACE_SCREENTARGET) ? " st" : ""));
5891
5892 /* Clip the box. */
5893 /** @todo Use [src|dst]SubResource to index p[Src|Dst]Surface->paMipmapLevels array directly. */
5894 uint32_t iSrcFace;
5895 uint32_t iSrcMipmap;
5896 vmsvga3dCalcMipmapAndFace(pSrcSurface->cLevels, srcSubResource, &iSrcMipmap, &iSrcFace);
5897
5898 uint32_t iDstFace;
5899 uint32_t iDstMipmap;
5900 vmsvga3dCalcMipmapAndFace(pDstSurface->cLevels, dstSubResource, &iDstMipmap, &iDstFace);
5901
5902 PVMSVGA3DMIPMAPLEVEL pSrcMipLevel;
5903 rc = vmsvga3dMipmapLevel(pSrcSurface, iSrcFace, iSrcMipmap, &pSrcMipLevel);
5904 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
5905
5906 PVMSVGA3DMIPMAPLEVEL pDstMipLevel;
5907 rc = vmsvga3dMipmapLevel(pDstSurface, iDstFace, iDstMipmap, &pDstMipLevel);
5908 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
5909
5910 SVGA3dCopyBox clipBox = *pBox;
5911 vmsvgaR3ClipCopyBox(&pSrcMipLevel->mipmapSize, &pDstMipLevel->mipmapSize, &clipBox);
5912
5913 UINT DstSubresource = dstSubResource;
5914 UINT DstX = clipBox.x;
5915 UINT DstY = clipBox.y;
5916 UINT DstZ = clipBox.z;
5917
5918 UINT SrcSubresource = srcSubResource;
5919 D3D11_BOX SrcBox;
5920 SrcBox.left = clipBox.srcx;
5921 SrcBox.top = clipBox.srcy;
5922 SrcBox.front = clipBox.srcz;
5923 SrcBox.right = clipBox.srcx + clipBox.w;
5924 SrcBox.bottom = clipBox.srcy + clipBox.h;
5925 SrcBox.back = clipBox.srcz + clipBox.d;
5926
5927 ID3D11Resource *pDstResource;
5928 ID3D11Resource *pSrcResource;
5929
5930 pDstResource = dxResource(pThisCC->svga.p3dState, pDstSurface, pDXContext);
5931 pSrcResource = dxResource(pThisCC->svga.p3dState, pSrcSurface, pDXContext);
5932
5933 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
5934 pSrcResource, SrcSubresource, &SrcBox);
5935
5936 pDstSurface->pBackendSurface->cidDrawing = pDXContext->cid;
5937 return VINF_SUCCESS;
5938}
5939
5940
5941static DECLCALLBACK(int) vmsvga3dBackDXPredCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5942{
5943 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5944
5945 RT_NOREF(pBackend, pDXContext);
5946 AssertFailed(); /** @todo Implement */
5947 return VERR_NOT_IMPLEMENTED;
5948}
5949
5950
5951static DECLCALLBACK(int) vmsvga3dBackDXPresentBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5952{
5953 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5954
5955 RT_NOREF(pBackend, pDXContext);
5956 AssertFailed(); /** @todo Implement */
5957 return VERR_NOT_IMPLEMENTED;
5958}
5959
5960
5961static DECLCALLBACK(int) vmsvga3dBackDXGenMips(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId)
5962{
5963 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5964 RT_NOREF(pBackend);
5965
5966 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
5967 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5968
5969 ID3D11ShaderResourceView *pShaderResourceView = pDXContext->pBackendDXContext->papShaderResourceView[shaderResourceViewId];
5970 AssertReturn(pShaderResourceView, VERR_INVALID_STATE);
5971
5972 uint32_t const sid = dxGetShaderResourceViewSid(pDXContext, shaderResourceViewId);
5973
5974 PVMSVGA3DSURFACE pSurface;
5975 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
5976 AssertRCReturn(rc, rc);
5977 AssertReturn(pSurface->pBackendSurface, VERR_INVALID_STATE);
5978
5979 pDevice->pImmediateContext->GenerateMips(pShaderResourceView);
5980
5981 pSurface->pBackendSurface->cidDrawing = pDXContext->cid;
5982 return VINF_SUCCESS;
5983}
5984
5985
5986static int dxDefineShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId, SVGACOTableDXSRViewEntry const *pEntry)
5987{
5988 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
5989 PVMSVGA3DSURFACE pSurface;
5990 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
5991 AssertRCReturn(rc, rc);
5992
5993 if (pSurface->pBackendSurface == NULL)
5994 {
5995 /* Create the actual texture. */
5996 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSurface);
5997 AssertRCReturn(rc, rc);
5998 }
5999
6000 HRESULT hr = dxShaderResourceViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pDXContext->pBackendDXContext->papShaderResourceView[shaderResourceViewId]);
6001 if (SUCCEEDED(hr))
6002 return VINF_SUCCESS;
6003 return VERR_INVALID_STATE;
6004}
6005
6006
6007static DECLCALLBACK(int) vmsvga3dBackDXDefineShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId, SVGACOTableDXSRViewEntry const *pEntry)
6008{
6009 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6010 RT_NOREF(pBackend);
6011
6012 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6013 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6014
6015 return dxDefineShaderResourceView(pThisCC, pDXContext, shaderResourceViewId, pEntry);
6016}
6017
6018
6019static DECLCALLBACK(int) vmsvga3dBackDXDestroyShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId)
6020{
6021 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6022 RT_NOREF(pBackend);
6023
6024 D3D_RELEASE(pDXContext->pBackendDXContext->papShaderResourceView[shaderResourceViewId]);
6025 return VINF_SUCCESS;
6026}
6027
6028
6029static int dxDefineRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGACOTableDXRTViewEntry const *pEntry)
6030{
6031 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
6032 PVMSVGA3DSURFACE pSurface;
6033 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
6034 AssertRCReturn(rc, rc);
6035
6036 if (pSurface->pBackendSurface == NULL)
6037 {
6038 /* Create the actual texture. */
6039 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSurface);
6040 AssertRCReturn(rc, rc);
6041 }
6042
6043 HRESULT hr = dxRenderTargetViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pDXContext->pBackendDXContext->papRenderTargetView[renderTargetViewId]);
6044 if (SUCCEEDED(hr))
6045 return VINF_SUCCESS;
6046
6047 return VERR_INVALID_STATE;
6048}
6049
6050
6051static DECLCALLBACK(int) vmsvga3dBackDXDefineRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGACOTableDXRTViewEntry const *pEntry)
6052{
6053 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6054 RT_NOREF(pBackend);
6055
6056 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6057 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6058
6059 return dxDefineRenderTargetView(pThisCC, pDXContext, renderTargetViewId, pEntry);
6060}
6061
6062
6063static DECLCALLBACK(int) vmsvga3dBackDXDestroyRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId)
6064{
6065 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6066 RT_NOREF(pBackend);
6067
6068 D3D_RELEASE(pDXContext->pBackendDXContext->papRenderTargetView[renderTargetViewId]);
6069 return VINF_SUCCESS;
6070}
6071
6072
6073static int dxDefineDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, SVGACOTableDXDSViewEntry const *pEntry)
6074{
6075 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
6076 PVMSVGA3DSURFACE pSurface;
6077 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
6078 AssertRCReturn(rc, rc);
6079
6080 if ( pSurface->pBackendSurface != NULL
6081 && pDXContext->cid != pSurface->idAssociatedContext)
6082 {
6083 /* Supposed to be per context. Sometimes the guest reuses the texture in another context. */
6084 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
6085 }
6086
6087 if (pSurface->pBackendSurface == NULL)
6088 {
6089 /* Create the actual texture. */
6090 rc = vmsvga3dBackSurfaceCreateDepthStencilTexture(pThisCC, pDXContext, pSurface);
6091 AssertRCReturn(rc, rc);
6092 }
6093
6094 HRESULT hr = dxDepthStencilViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pDXContext->pBackendDXContext->papDepthStencilView[depthStencilViewId]);
6095 if (SUCCEEDED(hr))
6096 return VINF_SUCCESS;
6097 return VERR_INVALID_STATE;
6098}
6099
6100static DECLCALLBACK(int) vmsvga3dBackDXDefineDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, SVGACOTableDXDSViewEntry const *pEntry)
6101{
6102 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6103 RT_NOREF(pBackend);
6104
6105 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6106 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6107
6108 return dxDefineDepthStencilView(pThisCC, pDXContext, depthStencilViewId, pEntry);
6109}
6110
6111
6112static DECLCALLBACK(int) vmsvga3dBackDXDestroyDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId)
6113{
6114 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6115 RT_NOREF(pBackend);
6116
6117 D3D_RELEASE(pDXContext->pBackendDXContext->papDepthStencilView[depthStencilViewId]);
6118 return VINF_SUCCESS;
6119}
6120
6121
6122static int dxDefineElementLayout(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId, SVGACOTableDXElementLayoutEntry const *pEntry)
6123{
6124 DXELEMENTLAYOUT *pDXElementLayout = &pDXContext->pBackendDXContext->paElementLayout[elementLayoutId];
6125 D3D_RELEASE(pDXElementLayout->pElementLayout);
6126
6127 /* Semantic name is not interpreted by D3D, therefore arbitrary names can be used
6128 * if they are consistent between the element layout and shader input signature.
6129 * "In general, data passed between pipeline stages is completely generic and is not uniquely
6130 * interpreted by the system; arbitrary semantics are allowed ..."
6131 *
6132 * However D3D runtime insists that "SemanticName string ("POSITIO1") cannot end with a number."
6133 *
6134 * System-Value semantics ("SV_*") between shaders require proper names of course.
6135 * But they are irrelevant for input attributes.
6136 */
6137 pDXElementLayout->cElementDesc = pEntry->numDescs;
6138 for (uint32_t i = 0; i < pEntry->numDescs; ++i)
6139 {
6140 D3D11_INPUT_ELEMENT_DESC *pDst = &pDXElementLayout->aElementDesc[i];
6141 SVGA3dInputElementDesc const *pSrc = &pEntry->descs[i];
6142 pDst->SemanticName = "ATTRIB";
6143 pDst->SemanticIndex = i; /// @todo 'pSrc->inputRegister' is unused, maybe it should somehow.
6144 pDst->Format = vmsvgaDXSurfaceFormat2Dxgi(pSrc->format);
6145 AssertReturn(pDst->Format != DXGI_FORMAT_UNKNOWN, VERR_NOT_IMPLEMENTED);
6146 pDst->InputSlot = pSrc->inputSlot;
6147 pDst->AlignedByteOffset = pSrc->alignedByteOffset;
6148 pDst->InputSlotClass = (D3D11_INPUT_CLASSIFICATION)pSrc->inputSlotClass;
6149 pDst->InstanceDataStepRate = pSrc->instanceDataStepRate;
6150 }
6151
6152 return VINF_SUCCESS;
6153}
6154
6155
6156static DECLCALLBACK(int) vmsvga3dBackDXDefineElementLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId, SVGACOTableDXElementLayoutEntry const *pEntry)
6157{
6158 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6159 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6160 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6161
6162 RT_NOREF(pBackend);
6163
6164 /* Not much can be done here because ID3D11Device::CreateInputLayout requires
6165 * a pShaderBytecodeWithInputSignature which is not known at this moment.
6166 * InputLayout object will be created in SVGA_3D_CMD_DX_SET_INPUT_LAYOUT.
6167 */
6168
6169 Assert(elementLayoutId == pEntry->elid);
6170
6171 return dxDefineElementLayout(pDXContext, elementLayoutId, pEntry);
6172}
6173
6174
6175static DECLCALLBACK(int) vmsvga3dBackDXDestroyElementLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6176{
6177 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6178
6179 RT_NOREF(pBackend, pDXContext);
6180 AssertFailed(); /** @todo Implement */
6181 return VERR_NOT_IMPLEMENTED;
6182}
6183
6184
6185static int dxDefineBlendState(PVMSVGA3DDXCONTEXT pDXContext,
6186 SVGA3dBlendStateId blendId, SVGACOTableDXBlendStateEntry const *pEntry)
6187{
6188 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6189 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6190
6191 HRESULT hr = dxBlendStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papBlendState[blendId]);
6192 if (SUCCEEDED(hr))
6193 return VINF_SUCCESS;
6194 return VERR_INVALID_STATE;
6195}
6196
6197static DECLCALLBACK(int) vmsvga3dBackDXDefineBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
6198 SVGA3dBlendStateId blendId, SVGACOTableDXBlendStateEntry const *pEntry)
6199{
6200 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6201 RT_NOREF(pBackend);
6202
6203 return dxDefineBlendState(pDXContext, blendId, pEntry);
6204}
6205
6206
6207static DECLCALLBACK(int) vmsvga3dBackDXDestroyBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6208{
6209 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6210
6211 RT_NOREF(pBackend, pDXContext);
6212 AssertFailed(); /** @todo Implement */
6213 return VERR_NOT_IMPLEMENTED;
6214}
6215
6216
6217static int dxDefineDepthStencilState(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId, SVGACOTableDXDepthStencilEntry const *pEntry)
6218{
6219 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6220 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6221
6222 HRESULT hr = dxDepthStencilStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papDepthStencilState[depthStencilId]);
6223 if (SUCCEEDED(hr))
6224 return VINF_SUCCESS;
6225 return VERR_INVALID_STATE;
6226}
6227
6228
6229static DECLCALLBACK(int) vmsvga3dBackDXDefineDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId, SVGACOTableDXDepthStencilEntry const *pEntry)
6230{
6231 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6232 RT_NOREF(pBackend);
6233
6234 return dxDefineDepthStencilState(pDXContext, depthStencilId, pEntry);
6235}
6236
6237
6238static DECLCALLBACK(int) vmsvga3dBackDXDestroyDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6239{
6240 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6241
6242 RT_NOREF(pBackend, pDXContext);
6243 AssertFailed(); /** @todo Implement */
6244 return VERR_NOT_IMPLEMENTED;
6245}
6246
6247
6248static int dxDefineRasterizerState(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId, SVGACOTableDXRasterizerStateEntry const *pEntry)
6249{
6250 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6251 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6252
6253 HRESULT hr = dxRasterizerStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papRasterizerState[rasterizerId]);
6254 if (SUCCEEDED(hr))
6255 return VINF_SUCCESS;
6256 return VERR_INVALID_STATE;
6257}
6258
6259
6260static DECLCALLBACK(int) vmsvga3dBackDXDefineRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId, SVGACOTableDXRasterizerStateEntry const *pEntry)
6261{
6262 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6263 RT_NOREF(pBackend);
6264
6265 return dxDefineRasterizerState(pDXContext, rasterizerId, pEntry);
6266}
6267
6268
6269static DECLCALLBACK(int) vmsvga3dBackDXDestroyRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6270{
6271 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6272
6273 RT_NOREF(pBackend, pDXContext);
6274 AssertFailed(); /** @todo Implement */
6275 return VERR_NOT_IMPLEMENTED;
6276}
6277
6278
6279static int dxDefineSamplerState(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSamplerId samplerId, SVGACOTableDXSamplerEntry const *pEntry)
6280{
6281 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6282 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6283
6284 HRESULT hr = dxSamplerStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papSamplerState[samplerId]);
6285 if (SUCCEEDED(hr))
6286 return VINF_SUCCESS;
6287 return VERR_INVALID_STATE;
6288}
6289
6290
6291static DECLCALLBACK(int) vmsvga3dBackDXDefineSamplerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSamplerId samplerId, SVGACOTableDXSamplerEntry const *pEntry)
6292{
6293 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6294 RT_NOREF(pBackend);
6295
6296 return dxDefineSamplerState(pDXContext, samplerId, pEntry);
6297}
6298
6299
6300static DECLCALLBACK(int) vmsvga3dBackDXDestroySamplerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6301{
6302 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6303
6304 RT_NOREF(pBackend, pDXContext);
6305 AssertFailed(); /** @todo Implement */
6306 return VERR_NOT_IMPLEMENTED;
6307}
6308
6309
6310
6311static int dxDefineShader(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, SVGACOTableDXShaderEntry const *pEntry)
6312{
6313 /** @todo A common approach for creation of COTable backend objects: runtime, empty DX COTable, live DX COTable. */
6314 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
6315 if (pDXShader->enmShaderType == SVGA3D_SHADERTYPE_INVALID)
6316 {
6317 /* Init the shader structure. */
6318 pDXShader->enmShaderType = pEntry->type;
6319 pDXShader->soid = SVGA_ID_INVALID;
6320 }
6321
6322 PVMSVGA3DSHADER pShader = &pDXContext->paShader[shaderId];
6323 pShader->u.pvBackendShader = pDXShader;
6324
6325 return VINF_SUCCESS;
6326}
6327
6328
6329static int dxDestroyShader(DXSHADER *pDXShader)
6330{
6331 pDXShader->enmShaderType = SVGA3D_SHADERTYPE_INVALID;
6332 D3D_RELEASE(pDXShader->pShader);
6333 RTMemFree(pDXShader->pvDXBC);
6334 pDXShader->pvDXBC = NULL;
6335 pDXShader->cbDXBC = 0;
6336 pDXShader->soid = SVGA_ID_INVALID;
6337 return VINF_SUCCESS;
6338}
6339
6340
6341static DECLCALLBACK(int) vmsvga3dBackDXDefineShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, SVGACOTableDXShaderEntry const *pEntry)
6342{
6343 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6344 RT_NOREF(pBackend);
6345
6346 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
6347 dxDestroyShader(pDXShader);
6348
6349 return dxDefineShader(pDXContext, shaderId, pEntry);
6350}
6351
6352
6353static DECLCALLBACK(int) vmsvga3dBackDXDestroyShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId)
6354{
6355 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6356 RT_NOREF(pBackend);
6357
6358 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
6359 dxDestroyShader(pDXShader);
6360
6361 return VINF_SUCCESS;
6362}
6363
6364
6365static DECLCALLBACK(int) vmsvga3dBackDXBindShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSHADER pShader, void const *pvShaderBytecode)
6366{
6367 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6368 DXDEVICE *pDevice = &pDXContext->pBackendDXContext->device;
6369 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6370
6371 RT_NOREF(pBackend);
6372
6373 int rc = VINF_SUCCESS;
6374
6375 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[pShader->id];
6376 Assert(pDXShader->enmShaderType == pShader->type);
6377
6378 if (pDXShader->pvDXBC)
6379 {
6380 RTMemFree(pDXShader->pvDXBC);
6381 pDXShader->pvDXBC = NULL;
6382 pDXShader->cbDXBC = 0;
6383 }
6384
6385 if (pvShaderBytecode)
6386 {
6387 Log(("Shader: cid=%u shid=%u type=%d\n", pDXContext->cid, pShader->id, pDXShader->enmShaderType));
6388
6389 rc = DXShaderCreateDXBC(&pShader->shaderInfo, &pDXShader->pvDXBC, &pDXShader->cbDXBC);
6390 if (RT_SUCCESS(rc))
6391 {
6392#ifdef LOG_ENABLED
6393 if (pBackend->pfnD3DDisassemble && LogIs6Enabled())
6394 {
6395 ID3D10Blob *pBlob = 0;
6396 HRESULT hr2 = pBackend->pfnD3DDisassemble(pDXShader->pvDXBC, pDXShader->cbDXBC, 0, NULL, &pBlob);
6397 if (SUCCEEDED(hr2) && pBlob && pBlob->GetBufferSize())
6398 Log6(("%s\n", pBlob->GetBufferPointer()));
6399 else
6400 AssertFailed();
6401 D3D_RELEASE(pBlob);
6402 }
6403#endif
6404
6405 HRESULT hr = dxShaderCreate(pDXContext, pShader, pDXShader);
6406 if (SUCCEEDED(hr))
6407 {
6408 }
6409 else
6410 rc = VERR_INVALID_STATE;
6411 }
6412 else
6413 rc = VERR_NO_MEMORY;
6414 }
6415
6416 return rc;
6417}
6418
6419
6420static DECLCALLBACK(int) vmsvga3dBackDXDefineStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid, SVGACOTableDXStreamOutputEntry const *pEntry)
6421{
6422 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6423 RT_NOREF(pBackend);
6424
6425 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
6426 dxDestroyStreamOutput(pDXStreamOutput);
6427
6428 return dxDefineStreamOutput(pDXContext, soid, pEntry);
6429}
6430
6431
6432static DECLCALLBACK(int) vmsvga3dBackDXDestroyStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid)
6433{
6434 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6435 RT_NOREF(pBackend);
6436
6437 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
6438 dxDestroyStreamOutput(pDXStreamOutput);
6439
6440 return VINF_SUCCESS;
6441}
6442
6443
6444static DECLCALLBACK(int) vmsvga3dBackDXSetStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid)
6445{
6446 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6447 RT_NOREF(pBackend, pDXContext, soid);
6448
6449 return VINF_SUCCESS;
6450}
6451
6452
6453static int dxCOTableRealloc(void **ppvCOTable, uint32_t *pcCOTable, uint32_t cbEntry, uint32_t cEntries, uint32_t cValidEntries)
6454{
6455 uint32_t const cCOTableCurrent = *pcCOTable;
6456
6457 if (*pcCOTable != cEntries)
6458 {
6459 /* Grow/shrink the array. */
6460 if (cEntries)
6461 {
6462 void *pvNew = RTMemRealloc(*ppvCOTable, cEntries * cbEntry);
6463 AssertReturn(pvNew, VERR_NO_MEMORY);
6464 *ppvCOTable = pvNew;
6465 }
6466 else
6467 {
6468 RTMemFree(*ppvCOTable);
6469 *ppvCOTable = NULL;
6470 }
6471
6472 *pcCOTable = cEntries;
6473 }
6474
6475 if (*ppvCOTable)
6476 {
6477 uint32_t const cEntriesToKeep = RT_MIN(cCOTableCurrent, cValidEntries);
6478 memset((uint8_t *)(*ppvCOTable) + cEntriesToKeep * cbEntry, 0, (cEntries - cEntriesToKeep) * cbEntry);
6479 }
6480
6481 return VINF_SUCCESS;
6482}
6483
6484static DECLCALLBACK(int) vmsvga3dBackDXSetCOTable(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableType type, uint32_t cValidEntries)
6485{
6486 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6487 RT_NOREF(pBackend);
6488
6489 VMSVGA3DBACKENDDXCONTEXT *pBackendDXContext = pDXContext->pBackendDXContext;
6490
6491 int rc = VINF_SUCCESS;
6492
6493 /*
6494 * 1) Release current backend table, if exists;
6495 * 2) Reallocate memory for the new backend table;
6496 * 3) If cValidEntries is not zero, then re-define corresponding backend table elements.
6497 */
6498 switch (type)
6499 {
6500 case SVGA_COTABLE_RTVIEW:
6501 /* Clear current entries. */
6502 if (pBackendDXContext->papRenderTargetView)
6503 {
6504 for (uint32_t i = cValidEntries; i < pBackendDXContext->cRenderTargetView; ++i)
6505 D3D_RELEASE(pBackendDXContext->papRenderTargetView[i]);
6506 }
6507
6508 rc = dxCOTableRealloc((void **)&pBackendDXContext->papRenderTargetView, &pBackendDXContext->cRenderTargetView,
6509 sizeof(pBackendDXContext->papRenderTargetView[0]), pDXContext->cot.cRTView, cValidEntries);
6510 AssertRCBreak(rc);
6511
6512 for (uint32_t i = 0; i < cValidEntries; ++i)
6513 {
6514 SVGACOTableDXRTViewEntry const *pEntry = &pDXContext->cot.paRTView[i];
6515 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6516 continue; /* Skip uninitialized entry. */
6517
6518 dxDefineRenderTargetView(pThisCC, pDXContext, i, pEntry);
6519 }
6520 break;
6521 case SVGA_COTABLE_DSVIEW:
6522 if (pBackendDXContext->papDepthStencilView)
6523 {
6524 for (uint32_t i = cValidEntries; i < pBackendDXContext->cDepthStencilView; ++i)
6525 D3D_RELEASE(pBackendDXContext->papDepthStencilView[i]);
6526 }
6527
6528 rc = dxCOTableRealloc((void **)&pBackendDXContext->papDepthStencilView, &pBackendDXContext->cDepthStencilView,
6529 sizeof(pBackendDXContext->papDepthStencilView[0]), pDXContext->cot.cDSView, cValidEntries);
6530 AssertRCBreak(rc);
6531
6532 for (uint32_t i = 0; i < cValidEntries; ++i)
6533 {
6534 SVGACOTableDXDSViewEntry const *pEntry = &pDXContext->cot.paDSView[i];
6535 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6536 continue; /* Skip uninitialized entry. */
6537
6538 dxDefineDepthStencilView(pThisCC, pDXContext, i, pEntry);
6539 }
6540 break;
6541 case SVGA_COTABLE_SRVIEW:
6542 if (pBackendDXContext->papShaderResourceView)
6543 {
6544 for (uint32_t i = cValidEntries; i < pBackendDXContext->cShaderResourceView; ++i)
6545 D3D_RELEASE(pBackendDXContext->papShaderResourceView[i]);
6546 }
6547
6548 rc = dxCOTableRealloc((void **)&pBackendDXContext->papShaderResourceView, &pBackendDXContext->cShaderResourceView,
6549 sizeof(pBackendDXContext->papShaderResourceView[0]), pDXContext->cot.cSRView, cValidEntries);
6550 AssertRCBreak(rc);
6551
6552 for (uint32_t i = 0; i < cValidEntries; ++i)
6553 {
6554 SVGACOTableDXSRViewEntry const *pEntry = &pDXContext->cot.paSRView[i];
6555 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6556 continue; /* Skip uninitialized entry. */
6557
6558 dxDefineShaderResourceView(pThisCC, pDXContext, i, pEntry);
6559 }
6560 break;
6561 case SVGA_COTABLE_ELEMENTLAYOUT:
6562 if (pBackendDXContext->paElementLayout)
6563 {
6564 for (uint32_t i = cValidEntries; i < pBackendDXContext->cElementLayout; ++i)
6565 D3D_RELEASE(pBackendDXContext->paElementLayout[i].pElementLayout);
6566 }
6567
6568 rc = dxCOTableRealloc((void **)&pBackendDXContext->paElementLayout, &pBackendDXContext->cElementLayout,
6569 sizeof(pBackendDXContext->paElementLayout[0]), pDXContext->cot.cElementLayout, cValidEntries);
6570 AssertRCBreak(rc);
6571
6572 for (uint32_t i = 0; i < cValidEntries; ++i)
6573 {
6574 SVGACOTableDXElementLayoutEntry const *pEntry = &pDXContext->cot.paElementLayout[i];
6575 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6576 continue; /* Skip uninitialized entry. */
6577
6578 dxDefineElementLayout(pDXContext, i, pEntry);
6579 }
6580 break;
6581 case SVGA_COTABLE_BLENDSTATE:
6582 if (pBackendDXContext->papBlendState)
6583 {
6584 for (uint32_t i = cValidEntries; i < pBackendDXContext->cBlendState; ++i)
6585 D3D_RELEASE(pBackendDXContext->papBlendState[i]);
6586 }
6587
6588 rc = dxCOTableRealloc((void **)&pBackendDXContext->papBlendState, &pBackendDXContext->cBlendState,
6589 sizeof(pBackendDXContext->papBlendState[0]), pDXContext->cot.cBlendState, cValidEntries);
6590 AssertRCBreak(rc);
6591
6592 for (uint32_t i = 0; i < cValidEntries; ++i)
6593 {
6594 SVGACOTableDXBlendStateEntry const *pEntry = &pDXContext->cot.paBlendState[i];
6595 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6596 continue; /* Skip uninitialized entry. */
6597
6598 dxDefineBlendState(pDXContext, i, pEntry);
6599 }
6600 break;
6601 case SVGA_COTABLE_DEPTHSTENCIL:
6602 if (pBackendDXContext->papDepthStencilState)
6603 {
6604 for (uint32_t i = cValidEntries; i < pBackendDXContext->cDepthStencilState; ++i)
6605 D3D_RELEASE(pBackendDXContext->papDepthStencilState[i]);
6606 }
6607
6608 rc = dxCOTableRealloc((void **)&pBackendDXContext->papDepthStencilState, &pBackendDXContext->cDepthStencilState,
6609 sizeof(pBackendDXContext->papDepthStencilState[0]), pDXContext->cot.cDepthStencil, cValidEntries);
6610 AssertRCBreak(rc);
6611
6612 for (uint32_t i = 0; i < cValidEntries; ++i)
6613 {
6614 SVGACOTableDXDepthStencilEntry const *pEntry = &pDXContext->cot.paDepthStencil[i];
6615 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6616 continue; /* Skip uninitialized entry. */
6617
6618 dxDefineDepthStencilState(pDXContext, i, pEntry);
6619 }
6620 break;
6621 case SVGA_COTABLE_RASTERIZERSTATE:
6622 if (pBackendDXContext->papRasterizerState)
6623 {
6624 for (uint32_t i = cValidEntries; i < pBackendDXContext->cRasterizerState; ++i)
6625 D3D_RELEASE(pBackendDXContext->papRasterizerState[i]);
6626 }
6627
6628 rc = dxCOTableRealloc((void **)&pBackendDXContext->papRasterizerState, &pBackendDXContext->cRasterizerState,
6629 sizeof(pBackendDXContext->papRasterizerState[0]), pDXContext->cot.cRasterizerState, cValidEntries);
6630 AssertRCBreak(rc);
6631
6632 for (uint32_t i = 0; i < cValidEntries; ++i)
6633 {
6634 SVGACOTableDXRasterizerStateEntry const *pEntry = &pDXContext->cot.paRasterizerState[i];
6635 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6636 continue; /* Skip uninitialized entry. */
6637
6638 dxDefineRasterizerState(pDXContext, i, pEntry);
6639 }
6640 break;
6641 case SVGA_COTABLE_SAMPLER:
6642 if (pBackendDXContext->papSamplerState)
6643 {
6644 for (uint32_t i = cValidEntries; i < pBackendDXContext->cSamplerState; ++i)
6645 D3D_RELEASE(pBackendDXContext->papSamplerState[i]);
6646 }
6647
6648 rc = dxCOTableRealloc((void **)&pBackendDXContext->papSamplerState, &pBackendDXContext->cSamplerState,
6649 sizeof(pBackendDXContext->papSamplerState[0]), pDXContext->cot.cSampler, cValidEntries);
6650 AssertRCBreak(rc);
6651
6652 for (uint32_t i = 0; i < cValidEntries; ++i)
6653 {
6654 SVGACOTableDXSamplerEntry const *pEntry = &pDXContext->cot.paSampler[i];
6655 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6656 continue; /* Skip uninitialized entry. */
6657
6658 dxDefineSamplerState(pDXContext, i, pEntry);
6659 }
6660 break;
6661 case SVGA_COTABLE_STREAMOUTPUT:
6662 if (pBackendDXContext->paStreamOutput)
6663 {
6664 for (uint32_t i = cValidEntries; i < pBackendDXContext->cStreamOutput; ++i)
6665 dxDestroyStreamOutput(&pBackendDXContext->paStreamOutput[i]);
6666 }
6667
6668 rc = dxCOTableRealloc((void **)&pBackendDXContext->paStreamOutput, &pBackendDXContext->cStreamOutput,
6669 sizeof(pBackendDXContext->paStreamOutput[0]), pDXContext->cot.cStreamOutput, cValidEntries);
6670 AssertRCBreak(rc);
6671
6672 for (uint32_t i = 0; i < cValidEntries; ++i)
6673 {
6674 SVGACOTableDXStreamOutputEntry const *pEntry = &pDXContext->cot.paStreamOutput[i];
6675 /** @todo The caller must verify the COTable content using same rules as when a new entry is defined. */
6676 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6677 continue; /* Skip uninitialized entry. */
6678
6679 dxDefineStreamOutput(pDXContext, i, pEntry);
6680 }
6681 break;
6682 case SVGA_COTABLE_DXQUERY:
6683 if (pBackendDXContext->papQuery)
6684 {
6685 for (uint32_t i = cValidEntries; i < pBackendDXContext->cQuery; ++i)
6686 D3D_RELEASE(pBackendDXContext->papQuery[i]);
6687 }
6688
6689 rc = dxCOTableRealloc((void **)&pBackendDXContext->papQuery, &pBackendDXContext->cQuery,
6690 sizeof(pBackendDXContext->papQuery[0]), pDXContext->cot.cQuery, cValidEntries);
6691 AssertRCBreak(rc);
6692
6693 for (uint32_t i = 0; i < cValidEntries; ++i)
6694 {
6695 SVGACOTableDXQueryEntry const *pEntry = &pDXContext->cot.paQuery[i];
6696 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6697 continue; /* Skip uninitialized entry. */
6698
6699 AssertFailed(); /** @todo implement */
6700 }
6701 break;
6702 case SVGA_COTABLE_DXSHADER:
6703 if (pBackendDXContext->paShader)
6704 {
6705 /* Destroy the no longer used entries. */
6706 for (uint32_t i = cValidEntries; i < pBackendDXContext->cShader; ++i)
6707 dxDestroyShader(&pBackendDXContext->paShader[i]);
6708 }
6709
6710 rc = dxCOTableRealloc((void **)&pBackendDXContext->paShader, &pBackendDXContext->cShader,
6711 sizeof(pBackendDXContext->paShader[0]), pDXContext->cot.cShader, cValidEntries);
6712 AssertRCBreak(rc);
6713
6714 for (uint32_t i = 0; i < cValidEntries; ++i)
6715 {
6716 SVGACOTableDXShaderEntry const *pEntry = &pDXContext->cot.paShader[i];
6717 /** @todo The caller must verify the COTable content using same rules as when a new entry is defined. */
6718 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
6719 continue; /* Skip uninitialized entry. */
6720
6721 /** @todo this should be in the common DX code (the caller). */
6722 PVMSVGA3DSHADER pShader = &pDXContext->paShader[i];
6723 pShader->id = i;
6724 pShader->cid = pDXContext->cid;
6725 pShader->type = pEntry->type;
6726 pShader->cbData = pEntry->sizeInBytes;
6727 pShader->pShaderProgram = NULL;
6728 pShader->u.pvBackendShader = NULL;
6729
6730 dxDefineShader(pDXContext, i, pEntry);
6731 }
6732 break;
6733 case SVGA_COTABLE_UAVIEW:
6734 AssertFailed(); /** @todo Implement */
6735 break;
6736 case SVGA_COTABLE_MAX: break; /* Compiler warning */
6737 }
6738 return rc;
6739}
6740
6741
6742static DECLCALLBACK(int) vmsvga3dBackDXBufferCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6743{
6744 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6745
6746 RT_NOREF(pBackend, pDXContext);
6747 AssertFailed(); /** @todo Implement */
6748 return VERR_NOT_IMPLEMENTED;
6749}
6750
6751
6752static DECLCALLBACK(int) vmsvga3dBackDXSurfaceCopyAndReadback(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6753{
6754 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6755
6756 RT_NOREF(pBackend, pDXContext);
6757 AssertFailed(); /** @todo Implement */
6758 return VERR_NOT_IMPLEMENTED;
6759}
6760
6761
6762static DECLCALLBACK(int) vmsvga3dBackDXMoveQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6763{
6764 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6765
6766 RT_NOREF(pBackend, pDXContext);
6767 AssertFailed(); /** @todo Implement */
6768 return VERR_NOT_IMPLEMENTED;
6769}
6770
6771
6772static DECLCALLBACK(int) vmsvga3dBackDXBindAllQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6773{
6774 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6775
6776 RT_NOREF(pBackend, pDXContext);
6777 AssertFailed(); /** @todo Implement */
6778 return VERR_NOT_IMPLEMENTED;
6779}
6780
6781
6782static DECLCALLBACK(int) vmsvga3dBackDXReadbackAllQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6783{
6784 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6785
6786 RT_NOREF(pBackend, pDXContext);
6787 AssertFailed(); /** @todo Implement */
6788 return VERR_NOT_IMPLEMENTED;
6789}
6790
6791
6792static DECLCALLBACK(int) vmsvga3dBackDXMobFence64(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6793{
6794 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6795
6796 RT_NOREF(pBackend, pDXContext);
6797 AssertFailed(); /** @todo Implement */
6798 return VERR_NOT_IMPLEMENTED;
6799}
6800
6801
6802static DECLCALLBACK(int) vmsvga3dBackDXBindAllShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6803{
6804 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6805
6806 RT_NOREF(pBackend, pDXContext);
6807 AssertFailed(); /** @todo Implement */
6808 return VERR_NOT_IMPLEMENTED;
6809}
6810
6811
6812static DECLCALLBACK(int) vmsvga3dBackDXHint(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6813{
6814 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6815
6816 RT_NOREF(pBackend, pDXContext);
6817 AssertFailed(); /** @todo Implement */
6818 return VERR_NOT_IMPLEMENTED;
6819}
6820
6821
6822static DECLCALLBACK(int) vmsvga3dBackDXBufferUpdate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6823{
6824 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6825
6826 RT_NOREF(pBackend, pDXContext);
6827 AssertFailed(); /** @todo Implement */
6828 return VERR_NOT_IMPLEMENTED;
6829}
6830
6831
6832static DECLCALLBACK(int) vmsvga3dBackDXSetVSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6833{
6834 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6835
6836 RT_NOREF(pBackend, pDXContext);
6837 AssertFailed(); /** @todo Implement */
6838 return VERR_NOT_IMPLEMENTED;
6839}
6840
6841
6842static DECLCALLBACK(int) vmsvga3dBackDXSetPSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6843{
6844 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6845
6846 RT_NOREF(pBackend, pDXContext);
6847 AssertFailed(); /** @todo Implement */
6848 return VERR_NOT_IMPLEMENTED;
6849}
6850
6851
6852static DECLCALLBACK(int) vmsvga3dBackDXSetGSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6853{
6854 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6855
6856 RT_NOREF(pBackend, pDXContext);
6857 AssertFailed(); /** @todo Implement */
6858 return VERR_NOT_IMPLEMENTED;
6859}
6860
6861
6862static DECLCALLBACK(int) vmsvga3dBackDXSetHSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6863{
6864 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6865
6866 RT_NOREF(pBackend, pDXContext);
6867 AssertFailed(); /** @todo Implement */
6868 return VERR_NOT_IMPLEMENTED;
6869}
6870
6871
6872static DECLCALLBACK(int) vmsvga3dBackDXSetDSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6873{
6874 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6875
6876 RT_NOREF(pBackend, pDXContext);
6877 AssertFailed(); /** @todo Implement */
6878 return VERR_NOT_IMPLEMENTED;
6879}
6880
6881
6882static DECLCALLBACK(int) vmsvga3dBackDXSetCSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6883{
6884 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6885
6886 RT_NOREF(pBackend, pDXContext);
6887 AssertFailed(); /** @todo Implement */
6888 return VERR_NOT_IMPLEMENTED;
6889}
6890
6891
6892static DECLCALLBACK(int) vmsvga3dBackDXCondBindAllShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6893{
6894 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6895
6896 RT_NOREF(pBackend, pDXContext);
6897 AssertFailed(); /** @todo Implement */
6898 return VERR_NOT_IMPLEMENTED;
6899}
6900
6901
6902static DECLCALLBACK(int) vmsvga3dBackScreenCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6903{
6904 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6905
6906 RT_NOREF(pBackend, pDXContext);
6907 AssertFailed(); /** @todo Implement */
6908 return VERR_NOT_IMPLEMENTED;
6909}
6910
6911
6912static DECLCALLBACK(int) vmsvga3dBackGrowOTable(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6913{
6914 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6915
6916 RT_NOREF(pBackend, pDXContext);
6917 AssertFailed(); /** @todo Implement */
6918 return VERR_NOT_IMPLEMENTED;
6919}
6920
6921
6922static DECLCALLBACK(int) vmsvga3dBackDXGrowCOTable(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6923{
6924 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6925
6926 RT_NOREF(pBackend, pDXContext);
6927 AssertFailed(); /** @todo Implement */
6928 return VERR_NOT_IMPLEMENTED;
6929}
6930
6931
6932static DECLCALLBACK(int) vmsvga3dBackIntraSurfaceCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6933{
6934 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6935
6936 RT_NOREF(pBackend, pDXContext);
6937 AssertFailed(); /** @todo Implement */
6938 return VERR_NOT_IMPLEMENTED;
6939}
6940
6941
6942static DECLCALLBACK(int) vmsvga3dBackDefineGBSurface_v3(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6943{
6944 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6945
6946 RT_NOREF(pBackend, pDXContext);
6947 AssertFailed(); /** @todo Implement */
6948 return VERR_NOT_IMPLEMENTED;
6949}
6950
6951
6952static DECLCALLBACK(int) vmsvga3dBackDXResolveCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6953{
6954 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6955
6956 RT_NOREF(pBackend, pDXContext);
6957 AssertFailed(); /** @todo Implement */
6958 return VERR_NOT_IMPLEMENTED;
6959}
6960
6961
6962static DECLCALLBACK(int) vmsvga3dBackDXPredResolveCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6963{
6964 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6965
6966 RT_NOREF(pBackend, pDXContext);
6967 AssertFailed(); /** @todo Implement */
6968 return VERR_NOT_IMPLEMENTED;
6969}
6970
6971
6972static DECLCALLBACK(int) vmsvga3dBackDXPredConvertRegion(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6973{
6974 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6975
6976 RT_NOREF(pBackend, pDXContext);
6977 AssertFailed(); /** @todo Implement */
6978 return VERR_NOT_IMPLEMENTED;
6979}
6980
6981
6982static DECLCALLBACK(int) vmsvga3dBackDXPredConvert(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6983{
6984 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6985
6986 RT_NOREF(pBackend, pDXContext);
6987 AssertFailed(); /** @todo Implement */
6988 return VERR_NOT_IMPLEMENTED;
6989}
6990
6991
6992static DECLCALLBACK(int) vmsvga3dBackWholeSurfaceCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6993{
6994 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6995
6996 RT_NOREF(pBackend, pDXContext);
6997 AssertFailed(); /** @todo Implement */
6998 return VERR_NOT_IMPLEMENTED;
6999}
7000
7001
7002static DECLCALLBACK(int) vmsvga3dBackDXDefineUAView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7003{
7004 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7005
7006 RT_NOREF(pBackend, pDXContext);
7007 AssertFailed(); /** @todo Implement */
7008 return VERR_NOT_IMPLEMENTED;
7009}
7010
7011
7012static DECLCALLBACK(int) vmsvga3dBackDXDestroyUAView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7013{
7014 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7015
7016 RT_NOREF(pBackend, pDXContext);
7017 AssertFailed(); /** @todo Implement */
7018 return VERR_NOT_IMPLEMENTED;
7019}
7020
7021
7022static DECLCALLBACK(int) vmsvga3dBackDXClearUAViewUint(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7023{
7024 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7025
7026 RT_NOREF(pBackend, pDXContext);
7027 AssertFailed(); /** @todo Implement */
7028 return VERR_NOT_IMPLEMENTED;
7029}
7030
7031
7032static DECLCALLBACK(int) vmsvga3dBackDXClearUAViewFloat(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7033{
7034 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7035
7036 RT_NOREF(pBackend, pDXContext);
7037 AssertFailed(); /** @todo Implement */
7038 return VERR_NOT_IMPLEMENTED;
7039}
7040
7041
7042static DECLCALLBACK(int) vmsvga3dBackDXCopyStructureCount(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7043{
7044 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7045
7046 RT_NOREF(pBackend, pDXContext);
7047 AssertFailed(); /** @todo Implement */
7048 return VERR_NOT_IMPLEMENTED;
7049}
7050
7051
7052static DECLCALLBACK(int) vmsvga3dBackDXSetUAViews(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7053{
7054 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7055
7056 RT_NOREF(pBackend, pDXContext);
7057 AssertFailed(); /** @todo Implement */
7058 return VERR_NOT_IMPLEMENTED;
7059}
7060
7061
7062static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexedInstancedIndirect(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7063{
7064 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7065
7066 RT_NOREF(pBackend, pDXContext);
7067 AssertFailed(); /** @todo Implement */
7068 return VERR_NOT_IMPLEMENTED;
7069}
7070
7071
7072static DECLCALLBACK(int) vmsvga3dBackDXDrawInstancedIndirect(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7073{
7074 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7075
7076 RT_NOREF(pBackend, pDXContext);
7077 AssertFailed(); /** @todo Implement */
7078 return VERR_NOT_IMPLEMENTED;
7079}
7080
7081
7082static DECLCALLBACK(int) vmsvga3dBackDXDispatch(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7083{
7084 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7085
7086 RT_NOREF(pBackend, pDXContext);
7087 AssertFailed(); /** @todo Implement */
7088 return VERR_NOT_IMPLEMENTED;
7089}
7090
7091
7092static DECLCALLBACK(int) vmsvga3dBackDXDispatchIndirect(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7093{
7094 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7095
7096 RT_NOREF(pBackend, pDXContext);
7097 AssertFailed(); /** @todo Implement */
7098 return VERR_NOT_IMPLEMENTED;
7099}
7100
7101
7102static DECLCALLBACK(int) vmsvga3dBackWriteZeroSurface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7103{
7104 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7105
7106 RT_NOREF(pBackend, pDXContext);
7107 AssertFailed(); /** @todo Implement */
7108 return VERR_NOT_IMPLEMENTED;
7109}
7110
7111
7112static DECLCALLBACK(int) vmsvga3dBackHintZeroSurface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7113{
7114 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7115
7116 RT_NOREF(pBackend, pDXContext);
7117 AssertFailed(); /** @todo Implement */
7118 return VERR_NOT_IMPLEMENTED;
7119}
7120
7121
7122static DECLCALLBACK(int) vmsvga3dBackDXTransferToBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7123{
7124 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7125
7126 RT_NOREF(pBackend, pDXContext);
7127 AssertFailed(); /** @todo Implement */
7128 return VERR_NOT_IMPLEMENTED;
7129}
7130
7131
7132static DECLCALLBACK(int) vmsvga3dBackDXSetStructureCount(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7133{
7134 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7135
7136 RT_NOREF(pBackend, pDXContext);
7137 AssertFailed(); /** @todo Implement */
7138 return VERR_NOT_IMPLEMENTED;
7139}
7140
7141
7142static DECLCALLBACK(int) vmsvga3dBackLogicOpsBitBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7143{
7144 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7145
7146 RT_NOREF(pBackend, pDXContext);
7147 AssertFailed(); /** @todo Implement */
7148 return VERR_NOT_IMPLEMENTED;
7149}
7150
7151
7152static DECLCALLBACK(int) vmsvga3dBackLogicOpsTransBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7153{
7154 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7155
7156 RT_NOREF(pBackend, pDXContext);
7157 AssertFailed(); /** @todo Implement */
7158 return VERR_NOT_IMPLEMENTED;
7159}
7160
7161
7162static DECLCALLBACK(int) vmsvga3dBackLogicOpsStretchBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7163{
7164 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7165
7166 RT_NOREF(pBackend, pDXContext);
7167 AssertFailed(); /** @todo Implement */
7168 return VERR_NOT_IMPLEMENTED;
7169}
7170
7171
7172static DECLCALLBACK(int) vmsvga3dBackLogicOpsColorFill(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7173{
7174 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7175
7176 RT_NOREF(pBackend, pDXContext);
7177 AssertFailed(); /** @todo Implement */
7178 return VERR_NOT_IMPLEMENTED;
7179}
7180
7181
7182static DECLCALLBACK(int) vmsvga3dBackLogicOpsAlphaBlend(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7183{
7184 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7185
7186 RT_NOREF(pBackend, pDXContext);
7187 AssertFailed(); /** @todo Implement */
7188 return VERR_NOT_IMPLEMENTED;
7189}
7190
7191
7192static DECLCALLBACK(int) vmsvga3dBackLogicOpsClearTypeBlend(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7193{
7194 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7195
7196 RT_NOREF(pBackend, pDXContext);
7197 AssertFailed(); /** @todo Implement */
7198 return VERR_NOT_IMPLEMENTED;
7199}
7200
7201
7202static DECLCALLBACK(int) vmsvga3dBackDefineGBSurface_v4(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7203{
7204 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7205
7206 RT_NOREF(pBackend, pDXContext);
7207 AssertFailed(); /** @todo Implement */
7208 return VERR_NOT_IMPLEMENTED;
7209}
7210
7211
7212static DECLCALLBACK(int) vmsvga3dBackDXSetCSUAViews(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7213{
7214 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7215
7216 RT_NOREF(pBackend, pDXContext);
7217 AssertFailed(); /** @todo Implement */
7218 return VERR_NOT_IMPLEMENTED;
7219}
7220
7221
7222static DECLCALLBACK(int) vmsvga3dBackDXSetMinLOD(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7223{
7224 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7225
7226 RT_NOREF(pBackend, pDXContext);
7227 AssertFailed(); /** @todo Implement */
7228 return VERR_NOT_IMPLEMENTED;
7229}
7230
7231
7232static DECLCALLBACK(int) vmsvga3dBackDXDefineStreamOutputWithMob(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7233{
7234 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7235
7236 RT_NOREF(pBackend, pDXContext);
7237 AssertFailed(); /** @todo Implement */
7238 return VERR_NOT_IMPLEMENTED;
7239}
7240
7241
7242static DECLCALLBACK(int) vmsvga3dBackDXSetShaderIface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7243{
7244 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7245
7246 RT_NOREF(pBackend, pDXContext);
7247 AssertFailed(); /** @todo Implement */
7248 return VERR_NOT_IMPLEMENTED;
7249}
7250
7251
7252static DECLCALLBACK(int) vmsvga3dBackDXBindStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7253{
7254 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7255
7256 RT_NOREF(pBackend, pDXContext);
7257 AssertFailed(); /** @todo Implement */
7258 return VERR_NOT_IMPLEMENTED;
7259}
7260
7261
7262static DECLCALLBACK(int) vmsvga3dBackSurfaceStretchBltNonMSToMS(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7263{
7264 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7265
7266 RT_NOREF(pBackend, pDXContext);
7267 AssertFailed(); /** @todo Implement */
7268 return VERR_NOT_IMPLEMENTED;
7269}
7270
7271
7272static DECLCALLBACK(int) vmsvga3dBackDXBindShaderIface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7273{
7274 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7275
7276 RT_NOREF(pBackend, pDXContext);
7277 AssertFailed(); /** @todo Implement */
7278 return VERR_NOT_IMPLEMENTED;
7279}
7280
7281
7282static DECLCALLBACK(int) vmsvga3dBackQueryInterface(PVGASTATECC pThisCC, char const *pszInterfaceName, void *pvInterfaceFuncs, size_t cbInterfaceFuncs)
7283{
7284 RT_NOREF(pThisCC);
7285
7286 int rc = VINF_SUCCESS;
7287 if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_DX) == 0)
7288 {
7289 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSDX))
7290 {
7291 if (pvInterfaceFuncs)
7292 {
7293 VMSVGA3DBACKENDFUNCSDX *p = (VMSVGA3DBACKENDFUNCSDX *)pvInterfaceFuncs;
7294 p->pfnDXDefineContext = vmsvga3dBackDXDefineContext;
7295 p->pfnDXDestroyContext = vmsvga3dBackDXDestroyContext;
7296 p->pfnDXBindContext = vmsvga3dBackDXBindContext;
7297 p->pfnDXReadbackContext = vmsvga3dBackDXReadbackContext;
7298 p->pfnDXInvalidateContext = vmsvga3dBackDXInvalidateContext;
7299 p->pfnDXSetSingleConstantBuffer = vmsvga3dBackDXSetSingleConstantBuffer;
7300 p->pfnDXSetShaderResources = vmsvga3dBackDXSetShaderResources;
7301 p->pfnDXSetShader = vmsvga3dBackDXSetShader;
7302 p->pfnDXSetSamplers = vmsvga3dBackDXSetSamplers;
7303 p->pfnDXDraw = vmsvga3dBackDXDraw;
7304 p->pfnDXDrawIndexed = vmsvga3dBackDXDrawIndexed;
7305 p->pfnDXDrawInstanced = vmsvga3dBackDXDrawInstanced;
7306 p->pfnDXDrawIndexedInstanced = vmsvga3dBackDXDrawIndexedInstanced;
7307 p->pfnDXDrawAuto = vmsvga3dBackDXDrawAuto;
7308 p->pfnDXSetInputLayout = vmsvga3dBackDXSetInputLayout;
7309 p->pfnDXSetVertexBuffers = vmsvga3dBackDXSetVertexBuffers;
7310 p->pfnDXSetIndexBuffer = vmsvga3dBackDXSetIndexBuffer;
7311 p->pfnDXSetTopology = vmsvga3dBackDXSetTopology;
7312 p->pfnDXSetRenderTargets = vmsvga3dBackDXSetRenderTargets;
7313 p->pfnDXSetBlendState = vmsvga3dBackDXSetBlendState;
7314 p->pfnDXSetDepthStencilState = vmsvga3dBackDXSetDepthStencilState;
7315 p->pfnDXSetRasterizerState = vmsvga3dBackDXSetRasterizerState;
7316 p->pfnDXDefineQuery = vmsvga3dBackDXDefineQuery;
7317 p->pfnDXDestroyQuery = vmsvga3dBackDXDestroyQuery;
7318 p->pfnDXBindQuery = vmsvga3dBackDXBindQuery;
7319 p->pfnDXSetQueryOffset = vmsvga3dBackDXSetQueryOffset;
7320 p->pfnDXBeginQuery = vmsvga3dBackDXBeginQuery;
7321 p->pfnDXEndQuery = vmsvga3dBackDXEndQuery;
7322 p->pfnDXReadbackQuery = vmsvga3dBackDXReadbackQuery;
7323 p->pfnDXSetPredication = vmsvga3dBackDXSetPredication;
7324 p->pfnDXSetSOTargets = vmsvga3dBackDXSetSOTargets;
7325 p->pfnDXSetViewports = vmsvga3dBackDXSetViewports;
7326 p->pfnDXSetScissorRects = vmsvga3dBackDXSetScissorRects;
7327 p->pfnDXClearRenderTargetView = vmsvga3dBackDXClearRenderTargetView;
7328 p->pfnDXClearDepthStencilView = vmsvga3dBackDXClearDepthStencilView;
7329 p->pfnDXPredCopyRegion = vmsvga3dBackDXPredCopyRegion;
7330 p->pfnDXPredCopy = vmsvga3dBackDXPredCopy;
7331 p->pfnDXPresentBlt = vmsvga3dBackDXPresentBlt;
7332 p->pfnDXGenMips = vmsvga3dBackDXGenMips;
7333 p->pfnDXDefineShaderResourceView = vmsvga3dBackDXDefineShaderResourceView;
7334 p->pfnDXDestroyShaderResourceView = vmsvga3dBackDXDestroyShaderResourceView;
7335 p->pfnDXDefineRenderTargetView = vmsvga3dBackDXDefineRenderTargetView;
7336 p->pfnDXDestroyRenderTargetView = vmsvga3dBackDXDestroyRenderTargetView;
7337 p->pfnDXDefineDepthStencilView = vmsvga3dBackDXDefineDepthStencilView;
7338 p->pfnDXDestroyDepthStencilView = vmsvga3dBackDXDestroyDepthStencilView;
7339 p->pfnDXDefineElementLayout = vmsvga3dBackDXDefineElementLayout;
7340 p->pfnDXDestroyElementLayout = vmsvga3dBackDXDestroyElementLayout;
7341 p->pfnDXDefineBlendState = vmsvga3dBackDXDefineBlendState;
7342 p->pfnDXDestroyBlendState = vmsvga3dBackDXDestroyBlendState;
7343 p->pfnDXDefineDepthStencilState = vmsvga3dBackDXDefineDepthStencilState;
7344 p->pfnDXDestroyDepthStencilState = vmsvga3dBackDXDestroyDepthStencilState;
7345 p->pfnDXDefineRasterizerState = vmsvga3dBackDXDefineRasterizerState;
7346 p->pfnDXDestroyRasterizerState = vmsvga3dBackDXDestroyRasterizerState;
7347 p->pfnDXDefineSamplerState = vmsvga3dBackDXDefineSamplerState;
7348 p->pfnDXDestroySamplerState = vmsvga3dBackDXDestroySamplerState;
7349 p->pfnDXDefineShader = vmsvga3dBackDXDefineShader;
7350 p->pfnDXDestroyShader = vmsvga3dBackDXDestroyShader;
7351 p->pfnDXBindShader = vmsvga3dBackDXBindShader;
7352 p->pfnDXDefineStreamOutput = vmsvga3dBackDXDefineStreamOutput;
7353 p->pfnDXDestroyStreamOutput = vmsvga3dBackDXDestroyStreamOutput;
7354 p->pfnDXSetStreamOutput = vmsvga3dBackDXSetStreamOutput;
7355 p->pfnDXSetCOTable = vmsvga3dBackDXSetCOTable;
7356 p->pfnDXBufferCopy = vmsvga3dBackDXBufferCopy;
7357 p->pfnDXSurfaceCopyAndReadback = vmsvga3dBackDXSurfaceCopyAndReadback;
7358 p->pfnDXMoveQuery = vmsvga3dBackDXMoveQuery;
7359 p->pfnDXBindAllQuery = vmsvga3dBackDXBindAllQuery;
7360 p->pfnDXReadbackAllQuery = vmsvga3dBackDXReadbackAllQuery;
7361 p->pfnDXMobFence64 = vmsvga3dBackDXMobFence64;
7362 p->pfnDXBindAllShader = vmsvga3dBackDXBindAllShader;
7363 p->pfnDXHint = vmsvga3dBackDXHint;
7364 p->pfnDXBufferUpdate = vmsvga3dBackDXBufferUpdate;
7365 p->pfnDXSetVSConstantBufferOffset = vmsvga3dBackDXSetVSConstantBufferOffset;
7366 p->pfnDXSetPSConstantBufferOffset = vmsvga3dBackDXSetPSConstantBufferOffset;
7367 p->pfnDXSetGSConstantBufferOffset = vmsvga3dBackDXSetGSConstantBufferOffset;
7368 p->pfnDXSetHSConstantBufferOffset = vmsvga3dBackDXSetHSConstantBufferOffset;
7369 p->pfnDXSetDSConstantBufferOffset = vmsvga3dBackDXSetDSConstantBufferOffset;
7370 p->pfnDXSetCSConstantBufferOffset = vmsvga3dBackDXSetCSConstantBufferOffset;
7371 p->pfnDXCondBindAllShader = vmsvga3dBackDXCondBindAllShader;
7372 p->pfnScreenCopy = vmsvga3dBackScreenCopy;
7373 p->pfnGrowOTable = vmsvga3dBackGrowOTable;
7374 p->pfnDXGrowCOTable = vmsvga3dBackDXGrowCOTable;
7375 p->pfnIntraSurfaceCopy = vmsvga3dBackIntraSurfaceCopy;
7376 p->pfnDefineGBSurface_v3 = vmsvga3dBackDefineGBSurface_v3;
7377 p->pfnDXResolveCopy = vmsvga3dBackDXResolveCopy;
7378 p->pfnDXPredResolveCopy = vmsvga3dBackDXPredResolveCopy;
7379 p->pfnDXPredConvertRegion = vmsvga3dBackDXPredConvertRegion;
7380 p->pfnDXPredConvert = vmsvga3dBackDXPredConvert;
7381 p->pfnWholeSurfaceCopy = vmsvga3dBackWholeSurfaceCopy;
7382 p->pfnDXDefineUAView = vmsvga3dBackDXDefineUAView;
7383 p->pfnDXDestroyUAView = vmsvga3dBackDXDestroyUAView;
7384 p->pfnDXClearUAViewUint = vmsvga3dBackDXClearUAViewUint;
7385 p->pfnDXClearUAViewFloat = vmsvga3dBackDXClearUAViewFloat;
7386 p->pfnDXCopyStructureCount = vmsvga3dBackDXCopyStructureCount;
7387 p->pfnDXSetUAViews = vmsvga3dBackDXSetUAViews;
7388 p->pfnDXDrawIndexedInstancedIndirect = vmsvga3dBackDXDrawIndexedInstancedIndirect;
7389 p->pfnDXDrawInstancedIndirect = vmsvga3dBackDXDrawInstancedIndirect;
7390 p->pfnDXDispatch = vmsvga3dBackDXDispatch;
7391 p->pfnDXDispatchIndirect = vmsvga3dBackDXDispatchIndirect;
7392 p->pfnWriteZeroSurface = vmsvga3dBackWriteZeroSurface;
7393 p->pfnHintZeroSurface = vmsvga3dBackHintZeroSurface;
7394 p->pfnDXTransferToBuffer = vmsvga3dBackDXTransferToBuffer;
7395 p->pfnDXSetStructureCount = vmsvga3dBackDXSetStructureCount;
7396 p->pfnLogicOpsBitBlt = vmsvga3dBackLogicOpsBitBlt;
7397 p->pfnLogicOpsTransBlt = vmsvga3dBackLogicOpsTransBlt;
7398 p->pfnLogicOpsStretchBlt = vmsvga3dBackLogicOpsStretchBlt;
7399 p->pfnLogicOpsColorFill = vmsvga3dBackLogicOpsColorFill;
7400 p->pfnLogicOpsAlphaBlend = vmsvga3dBackLogicOpsAlphaBlend;
7401 p->pfnLogicOpsClearTypeBlend = vmsvga3dBackLogicOpsClearTypeBlend;
7402 p->pfnDefineGBSurface_v4 = vmsvga3dBackDefineGBSurface_v4;
7403 p->pfnDXSetCSUAViews = vmsvga3dBackDXSetCSUAViews;
7404 p->pfnDXSetMinLOD = vmsvga3dBackDXSetMinLOD;
7405 p->pfnDXDefineStreamOutputWithMob = vmsvga3dBackDXDefineStreamOutputWithMob;
7406 p->pfnDXSetShaderIface = vmsvga3dBackDXSetShaderIface;
7407 p->pfnDXBindStreamOutput = vmsvga3dBackDXBindStreamOutput;
7408 p->pfnSurfaceStretchBltNonMSToMS = vmsvga3dBackSurfaceStretchBltNonMSToMS;
7409 p->pfnDXBindShaderIface = vmsvga3dBackDXBindShaderIface;
7410 }
7411 }
7412 else
7413 {
7414 AssertFailed();
7415 rc = VERR_INVALID_PARAMETER;
7416 }
7417 }
7418 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_MAP) == 0)
7419 {
7420 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSMAP))
7421 {
7422 if (pvInterfaceFuncs)
7423 {
7424 VMSVGA3DBACKENDFUNCSMAP *p = (VMSVGA3DBACKENDFUNCSMAP *)pvInterfaceFuncs;
7425 p->pfnSurfaceMap = vmsvga3dBackSurfaceMap;
7426 p->pfnSurfaceUnmap = vmsvga3dBackSurfaceUnmap;
7427 }
7428 }
7429 else
7430 {
7431 AssertFailed();
7432 rc = VERR_INVALID_PARAMETER;
7433 }
7434 }
7435 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_GBO) == 0)
7436 {
7437 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSGBO))
7438 {
7439 if (pvInterfaceFuncs)
7440 {
7441 VMSVGA3DBACKENDFUNCSGBO *p = (VMSVGA3DBACKENDFUNCSGBO *)pvInterfaceFuncs;
7442 p->pfnScreenTargetBind = vmsvga3dScreenTargetBind;
7443 p->pfnScreenTargetUpdate = vmsvga3dScreenTargetUpdate;
7444 }
7445 }
7446 else
7447 {
7448 AssertFailed();
7449 rc = VERR_INVALID_PARAMETER;
7450 }
7451 }
7452 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_3D) == 0)
7453 {
7454 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCS3D))
7455 {
7456 if (pvInterfaceFuncs)
7457 {
7458 VMSVGA3DBACKENDFUNCS3D *p = (VMSVGA3DBACKENDFUNCS3D *)pvInterfaceFuncs;
7459 p->pfnInit = vmsvga3dBackInit;
7460 p->pfnPowerOn = vmsvga3dBackPowerOn;
7461 p->pfnTerminate = vmsvga3dBackTerminate;
7462 p->pfnReset = vmsvga3dBackReset;
7463 p->pfnQueryCaps = vmsvga3dBackQueryCaps;
7464 p->pfnChangeMode = vmsvga3dBackChangeMode;
7465 p->pfnCreateTexture = vmsvga3dBackCreateTexture;
7466 p->pfnSurfaceDestroy = vmsvga3dBackSurfaceDestroy;
7467 p->pfnSurfaceCopy = vmsvga3dBackSurfaceCopy;
7468 p->pfnSurfaceDMACopyBox = vmsvga3dBackSurfaceDMACopyBox;
7469 p->pfnSurfaceStretchBlt = vmsvga3dBackSurfaceStretchBlt;
7470 p->pfnUpdateHostScreenViewport = vmsvga3dBackUpdateHostScreenViewport;
7471 p->pfnDefineScreen = vmsvga3dBackDefineScreen;
7472 p->pfnDestroyScreen = vmsvga3dBackDestroyScreen;
7473 p->pfnSurfaceBlitToScreen = vmsvga3dBackSurfaceBlitToScreen;
7474 p->pfnSurfaceUpdateHeapBuffers = vmsvga3dBackSurfaceUpdateHeapBuffers;
7475 }
7476 }
7477 else
7478 {
7479 AssertFailed();
7480 rc = VERR_INVALID_PARAMETER;
7481 }
7482 }
7483 else
7484 rc = VERR_NOT_IMPLEMENTED;
7485 return rc;
7486}
7487
7488
7489extern VMSVGA3DBACKENDDESC const g_BackendDX =
7490{
7491 "DX",
7492 vmsvga3dBackQueryInterface
7493};
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