VirtualBox

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

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

Devices/Graphics: saved state fixes: bugref:9830

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