VirtualBox

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

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

Devices/Graphics: extended debug code to support float textures: bugref:9830

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 326.7 KB
Line 
1/* $Id: DevVGA-SVGA3d-win-dx.cpp 94223 2022-03-14 13:09:42Z 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->format = pSurface->format;
3243 pMap->box = clipBox;
3244 pMap->cbPixel = pSurface->cbBlock;
3245 pMap->cbRowPitch = mappedResource.RowPitch;
3246 pMap->cbDepthPitch = mappedResource.DepthPitch;
3247 pMap->pvData = (uint8_t *)mappedResource.pData
3248 + pMap->box.x * pMap->cbPixel
3249 + pMap->box.y * pMap->cbRowPitch
3250 + pMap->box.z * pMap->cbDepthPitch;
3251 }
3252 else
3253 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
3254 }
3255 else if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
3256 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_CUBE
3257 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3258 {
3259//Assert(pImage->face == 0 && pImage->mipmap == 0);
3260if (!( (pBackendSurface->pStagingTexture && pBackendSurface->pDynamicTexture)
3261 || (pBackendSurface->pStagingTexture3D && pBackendSurface->pDynamicTexture3D)
3262 )
3263 )
3264{
3265 AssertFailed();
3266 return VERR_NOT_IMPLEMENTED;
3267}
3268
3269 dxSurfaceWait(pState, pSurface, pSurface->idAssociatedContext);
3270
3271 ID3D11Resource *pMappedResource;
3272 if (enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3273 {
3274 pMappedResource = (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3275 ? (ID3D11Resource *)pBackendSurface->pStagingTexture3D
3276 : (ID3D11Resource *)pBackendSurface->pStagingTexture;
3277
3278 /* Copy the texture content to the staging texture.
3279 * The requested miplevel of the texture is copied to the miplevel 0 of the staging texture,
3280 * because the staging (and dynamic) structures do not have miplevels.
3281 * Always copy entire miplevel so all Dst are zero and pSrcBox is NULL, as D3D11 requires.
3282 */
3283 ID3D11Resource *pDstResource = pMappedResource;
3284 UINT DstSubresource = 0;
3285 UINT DstX = 0;
3286 UINT DstY = 0;
3287 UINT DstZ = 0;
3288 ID3D11Resource *pSrcResource = pBackendSurface->u.pResource;
3289 UINT SrcSubresource = D3D11CalcSubresource(pImage->mipmap, pImage->face, pSurface->cLevels);
3290 D3D11_BOX *pSrcBox = NULL;
3291 //D3D11_BOX SrcBox;
3292 //SrcBox.left = 0;
3293 //SrcBox.top = 0;
3294 //SrcBox.front = 0;
3295 //SrcBox.right = pMipLevel->mipmapSize.width;
3296 //SrcBox.bottom = pMipLevel->mipmapSize.height;
3297 //SrcBox.back = pMipLevel->mipmapSize.depth;
3298 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3299 pSrcResource, SrcSubresource, pSrcBox);
3300 }
3301 else if (enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
3302 pMappedResource = (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3303 ? (ID3D11Resource *)pBackendSurface->pStagingTexture3D
3304 : (ID3D11Resource *)pBackendSurface->pStagingTexture;
3305 else
3306 pMappedResource = (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3307 ? (ID3D11Resource *)pBackendSurface->pDynamicTexture3D
3308 : (ID3D11Resource *)pBackendSurface->pDynamicTexture;
3309
3310 UINT const Subresource = 0;
3311 HRESULT hr = pDevice->pImmediateContext->Map(pMappedResource, Subresource,
3312 d3d11MapType, /* MapFlags = */ 0, &mappedResource);
3313 if (SUCCEEDED(hr))
3314 {
3315 pMap->enmMapType = enmMapType;
3316 pMap->format = pSurface->format;
3317 pMap->box = clipBox;
3318 pMap->cbPixel = pSurface->cbBlock;
3319 pMap->cbRowPitch = mappedResource.RowPitch;
3320 pMap->cbDepthPitch = mappedResource.DepthPitch;
3321 pMap->pvData = (uint8_t *)mappedResource.pData
3322 + pMap->box.x * pMap->cbPixel
3323 + pMap->box.y * pMap->cbRowPitch
3324 + pMap->box.z * pMap->cbDepthPitch;
3325 }
3326 else
3327 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
3328 }
3329 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
3330 {
3331 /* Map the staging buffer. */
3332 rc = dxStagingBufferRealloc(pDevice, pMipLevel->cbSurface);
3333 if (RT_SUCCESS(rc))
3334 {
3335 /* The staging buffer does not allow D3D11_MAP_WRITE_DISCARD, so replace it. */
3336 if (d3d11MapType == D3D11_MAP_WRITE_DISCARD)
3337 d3d11MapType = D3D11_MAP_WRITE;
3338
3339 if (enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3340 {
3341 /* Copy from the buffer to the staging buffer. */
3342 ID3D11Resource *pDstResource = pDevice->pStagingBuffer;
3343 UINT DstSubresource = 0;
3344 UINT DstX = clipBox.x;
3345 UINT DstY = clipBox.y;
3346 UINT DstZ = clipBox.z;
3347 ID3D11Resource *pSrcResource = pBackendSurface->u.pResource;
3348 UINT SrcSubresource = 0;
3349 D3D11_BOX SrcBox;
3350 SrcBox.left = clipBox.x;
3351 SrcBox.top = clipBox.y;
3352 SrcBox.front = clipBox.z;
3353 SrcBox.right = clipBox.w;
3354 SrcBox.bottom = clipBox.h;
3355 SrcBox.back = clipBox.d;
3356 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3357 pSrcResource, SrcSubresource, &SrcBox);
3358 }
3359
3360 UINT const Subresource = 0; /* Buffers have only one subresource. */
3361 HRESULT hr = pDevice->pImmediateContext->Map(pDevice->pStagingBuffer, Subresource,
3362 d3d11MapType, /* MapFlags = */ 0, &mappedResource);
3363 if (SUCCEEDED(hr))
3364 {
3365 pMap->enmMapType = enmMapType;
3366 pMap->format = pSurface->format;
3367 pMap->box = clipBox;
3368 pMap->cbPixel = pSurface->cbBlock;
3369 pMap->cbRowPitch = mappedResource.RowPitch;
3370 pMap->cbDepthPitch = mappedResource.DepthPitch;
3371 pMap->pvData = (uint8_t *)mappedResource.pData
3372 + pMap->box.x * pMap->cbPixel
3373 + pMap->box.y * pMap->cbRowPitch
3374 + pMap->box.z * pMap->cbDepthPitch;
3375 }
3376 else
3377 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
3378 }
3379 }
3380 else
3381 {
3382 // UINT D3D11CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT MipLevels);
3383 /** @todo Implement. */
3384 AssertFailed();
3385 rc = VERR_NOT_IMPLEMENTED;
3386 }
3387
3388 return rc;
3389}
3390
3391
3392static DECLCALLBACK(int) vmsvga3dBackSurfaceUnmap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, VMSVGA3D_MAPPED_SURFACE *pMap, bool fWritten)
3393{
3394 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3395 AssertReturn(pState, VERR_INVALID_STATE);
3396
3397 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3398 AssertReturn(pBackend, VERR_INVALID_STATE);
3399
3400 PVMSVGA3DSURFACE pSurface;
3401 int rc = vmsvga3dSurfaceFromSid(pState, pImage->sid, &pSurface);
3402 AssertRCReturn(rc, rc);
3403
3404 /* The called should not use the function for system memory surfaces. */
3405 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
3406 AssertReturn(pBackendSurface, VERR_INVALID_PARAMETER);
3407
3408 PVMSVGA3DMIPMAPLEVEL pMipLevel;
3409 rc = vmsvga3dMipmapLevel(pSurface, pImage->face, pImage->mipmap, &pMipLevel);
3410 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
3411
3412 /* A surface is always mapped by the DX context which has created the surface. */
3413 DXDEVICE *pDevice = dxDeviceFromCid(pSurface->idAssociatedContext, pState);
3414 AssertReturn(pDevice && pDevice->pDevice, VERR_INVALID_STATE);
3415
3416 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
3417 {
3418 ID3D11Texture2D *pMappedTexture;
3419 if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3420 pMappedTexture = pBackendSurface->pStagingTexture;
3421 else if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
3422 pMappedTexture = pBackendSurface->pStagingTexture;
3423 else
3424 pMappedTexture = pBackendSurface->pDynamicTexture;
3425
3426 UINT const Subresource = 0; /* Screen target surfaces have only one subresource. */
3427 pDevice->pImmediateContext->Unmap(pMappedTexture, Subresource);
3428
3429 if ( fWritten
3430 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
3431 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
3432 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
3433 {
3434 ID3D11Resource *pDstResource = pBackendSurface->u.pTexture2D;
3435 UINT DstSubresource = Subresource;
3436 UINT DstX = pMap->box.x;
3437 UINT DstY = pMap->box.y;
3438 UINT DstZ = pMap->box.z;
3439 ID3D11Resource *pSrcResource = pMappedTexture;
3440 UINT SrcSubresource = Subresource;
3441 D3D11_BOX SrcBox;
3442 SrcBox.left = pMap->box.x;
3443 SrcBox.top = pMap->box.y;
3444 SrcBox.front = pMap->box.z;
3445 SrcBox.right = pMap->box.x + pMap->box.w;
3446 SrcBox.bottom = pMap->box.y + pMap->box.h;
3447 SrcBox.back = pMap->box.z + pMap->box.d;
3448
3449 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3450 pSrcResource, SrcSubresource, &SrcBox);
3451
3452 pBackendSurface->cidDrawing = pSurface->idAssociatedContext;
3453 }
3454 }
3455 else if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
3456 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_CUBE
3457 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3458 {
3459 ID3D11Resource *pMappedResource;
3460 if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3461 pMappedResource = (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3462 ? (ID3D11Resource *)pBackendSurface->pStagingTexture3D
3463 : (ID3D11Resource *)pBackendSurface->pStagingTexture;
3464 else if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
3465 pMappedResource = (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3466 ? (ID3D11Resource *)pBackendSurface->pStagingTexture3D
3467 : (ID3D11Resource *)pBackendSurface->pStagingTexture;
3468 else
3469 pMappedResource = (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3470 ? (ID3D11Resource *)pBackendSurface->pDynamicTexture3D
3471 : (ID3D11Resource *)pBackendSurface->pDynamicTexture;
3472
3473 UINT const Subresource = 0; /* Staging or dynamic textures have one subresource. */
3474 pDevice->pImmediateContext->Unmap(pMappedResource, Subresource);
3475
3476 if ( fWritten
3477 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
3478 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
3479 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
3480 {
3481 /* If entire resource must be copied then use pSrcBox = NULL and dst point (0,0,0)
3482 * Because DX11 insists on this for some resource types, for example DEPTH_STENCIL resources.
3483 */
3484 uint32_t const cWidth0 = pSurface->paMipmapLevels[0].mipmapSize.width;
3485 uint32_t const cHeight0 = pSurface->paMipmapLevels[0].mipmapSize.height;
3486 uint32_t const cDepth0 = pSurface->paMipmapLevels[0].mipmapSize.depth;
3487 bool const fEntireResource = pMap->box.x == 0 && pMap->box.y == 0 && pMap->box.z == 0
3488 && pMap->box.w == cWidth0 && pMap->box.h == cHeight0 && pMap->box.d == cDepth0;
3489
3490 ID3D11Resource *pDstResource = pBackendSurface->u.pResource;
3491 UINT DstSubresource = D3D11CalcSubresource(pImage->mipmap, pImage->face, pSurface->cLevels);
3492 UINT DstX = (pMap->box.x / pSurface->cxBlock) * pSurface->cxBlock;
3493 UINT DstY = (pMap->box.y / pSurface->cyBlock) * pSurface->cyBlock;
3494 UINT DstZ = pMap->box.z;
3495 ID3D11Resource *pSrcResource = pMappedResource;
3496 UINT SrcSubresource = Subresource;
3497 D3D11_BOX *pSrcBox;
3498 D3D11_BOX SrcBox;
3499 if (fEntireResource)
3500 pSrcBox = NULL;
3501 else
3502 {
3503 uint32_t const cxBlocks = (pMap->box.w + pSurface->cxBlock - 1) / pSurface->cxBlock;
3504 uint32_t const cyBlocks = (pMap->box.h + pSurface->cyBlock - 1) / pSurface->cyBlock;
3505
3506 SrcBox.left = DstX;
3507 SrcBox.top = DstY;
3508 SrcBox.front = DstZ;
3509 SrcBox.right = DstX + cxBlocks * pSurface->cxBlock;
3510 SrcBox.bottom = DstY + cyBlocks * pSurface->cyBlock;
3511 SrcBox.back = DstZ + pMap->box.d;
3512 pSrcBox = &SrcBox;
3513 }
3514
3515 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3516 pSrcResource, SrcSubresource, pSrcBox);
3517
3518 pBackendSurface->cidDrawing = pSurface->idAssociatedContext;
3519 }
3520 }
3521 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
3522 {
3523 /* Unmap the staging buffer. */
3524 UINT const Subresource = 0; /* Buffers have only one subresource. */
3525 pDevice->pImmediateContext->Unmap(pDevice->pStagingBuffer, Subresource);
3526
3527 /* Copy from the staging buffer to the actual buffer */
3528 if ( fWritten
3529 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
3530 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
3531 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
3532 {
3533 ID3D11Resource *pDstResource = pBackendSurface->u.pResource;
3534 UINT DstSubresource = 0;
3535 UINT DstX = (pMap->box.x / pSurface->cxBlock) * pSurface->cxBlock;
3536 UINT DstY = (pMap->box.y / pSurface->cyBlock) * pSurface->cyBlock;
3537 UINT DstZ = pMap->box.z;
3538 ID3D11Resource *pSrcResource = pDevice->pStagingBuffer;
3539 UINT SrcSubresource = 0;
3540 D3D11_BOX SrcBox;
3541
3542 uint32_t const cxBlocks = (pMap->box.w + pSurface->cxBlock - 1) / pSurface->cxBlock;
3543 uint32_t const cyBlocks = (pMap->box.h + pSurface->cyBlock - 1) / pSurface->cyBlock;
3544
3545 SrcBox.left = DstX;
3546 SrcBox.top = DstY;
3547 SrcBox.front = DstZ;
3548 SrcBox.right = DstX + cxBlocks * pSurface->cxBlock;
3549 SrcBox.bottom = DstY + cyBlocks * pSurface->cyBlock;
3550 SrcBox.back = DstZ + pMap->box.d;
3551
3552 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3553 pSrcResource, SrcSubresource, &SrcBox);
3554 }
3555 }
3556 else
3557 {
3558 AssertFailed();
3559 rc = VERR_NOT_IMPLEMENTED;
3560 }
3561
3562 return rc;
3563}
3564
3565
3566static DECLCALLBACK(int) vmsvga3dScreenTargetBind(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, uint32_t sid)
3567{
3568 int rc = VINF_SUCCESS;
3569
3570 PVMSVGA3DSURFACE pSurface;
3571 if (sid != SVGA_ID_INVALID)
3572 {
3573 /* Create the surface if does not yet exist. */
3574 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3575 AssertReturn(pState, VERR_INVALID_STATE);
3576
3577 rc = vmsvga3dSurfaceFromSid(pState, sid, &pSurface);
3578 AssertRCReturn(rc, rc);
3579
3580 if (!VMSVGA3DSURFACE_HAS_HW_SURFACE(pSurface))
3581 {
3582 /* Create the actual texture. */
3583 rc = vmsvga3dBackSurfaceCreateScreenTarget(pThisCC, pSurface);
3584 AssertRCReturn(rc, rc);
3585 }
3586 }
3587 else
3588 pSurface = NULL;
3589
3590 /* Notify the HW accelerated screen if it is used. */
3591 VMSVGAHWSCREEN *pHwScreen = pScreen->pHwScreen;
3592 if (!pHwScreen)
3593 return VINF_SUCCESS;
3594
3595 /* Same surface -> do nothing. */
3596 if (pHwScreen->sidScreenTarget == sid)
3597 return VINF_SUCCESS;
3598
3599 if (sid != SVGA_ID_INVALID)
3600 {
3601 AssertReturn( pSurface->pBackendSurface
3602 && pSurface->pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET, VERR_INVALID_PARAMETER);
3603
3604 HANDLE const hSharedSurface = pHwScreen->SharedHandle;
3605 rc = vmsvga3dDrvNotifyBindSurface(pThisCC, pScreen, hSharedSurface);
3606 }
3607
3608 if (RT_SUCCESS(rc))
3609 {
3610 pHwScreen->sidScreenTarget = sid;
3611 }
3612
3613 return rc;
3614}
3615
3616
3617static DECLCALLBACK(int) vmsvga3dScreenTargetUpdate(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, SVGA3dRect const *pRect)
3618{
3619 VMSVGAHWSCREEN *pHwScreen = pScreen->pHwScreen;
3620 AssertReturn(pHwScreen, VERR_NOT_SUPPORTED);
3621
3622 if (pHwScreen->sidScreenTarget == SVGA_ID_INVALID)
3623 return VINF_SUCCESS; /* No surface bound. */
3624
3625 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3626 AssertReturn(pState, VERR_INVALID_STATE);
3627
3628 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3629 AssertReturn(pBackend, VERR_INVALID_STATE);
3630
3631 PVMSVGA3DSURFACE pSurface;
3632 int rc = vmsvga3dSurfaceFromSid(pState, pHwScreen->sidScreenTarget, &pSurface);
3633 AssertRCReturn(rc, rc);
3634
3635 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
3636 AssertReturn(pBackendSurface && pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET, VERR_INVALID_PARAMETER);
3637
3638 SVGA3dRect boundRect;
3639 boundRect.x = 0;
3640 boundRect.y = 0;
3641 boundRect.w = pSurface->paMipmapLevels[0].mipmapSize.width;
3642 boundRect.h = pSurface->paMipmapLevels[0].mipmapSize.height;
3643 SVGA3dRect clipRect = *pRect;
3644 vmsvgaR3Clip3dRect(&boundRect, &clipRect);
3645 ASSERT_GUEST_RETURN(clipRect.w && clipRect.h, VERR_INVALID_PARAMETER);
3646
3647 /* Wait for the surface to finish drawing. */
3648 dxSurfaceWait(pState, pSurface, DX_CID_BACKEND);
3649
3650 /* Copy the screen texture to the shared surface. */
3651 DWORD result = pHwScreen->pDXGIKeyedMutex->AcquireSync(0, 10000);
3652 if (result == S_OK)
3653 {
3654 pBackend->dxDevice.pImmediateContext->CopyResource(pHwScreen->pTexture, pBackendSurface->u.pTexture2D);
3655
3656 dxDeviceFlush(&pBackend->dxDevice);
3657
3658 result = pHwScreen->pDXGIKeyedMutex->ReleaseSync(1);
3659 }
3660 else
3661 AssertFailed();
3662
3663 rc = vmsvga3dDrvNotifyUpdate(pThisCC, pScreen, pRect->x, pRect->y, pRect->w, pRect->h);
3664 return rc;
3665}
3666
3667
3668/*
3669 *
3670 * 3D interface.
3671 *
3672 */
3673
3674static DECLCALLBACK(int) vmsvga3dBackQueryCaps(PVGASTATECC pThisCC, SVGA3dDevCapIndex idx3dCaps, uint32_t *pu32Val)
3675{
3676 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3677 AssertReturn(pState, VERR_INVALID_STATE);
3678
3679 int rc = VINF_SUCCESS;
3680
3681 *pu32Val = 0;
3682
3683 if (idx3dCaps > SVGA3D_DEVCAP_MAX)
3684 {
3685 LogRelMax(16, ("VMSVGA: unsupported SVGA3D_DEVCAP %d\n", idx3dCaps));
3686 return VERR_NOT_SUPPORTED;
3687 }
3688
3689 D3D_FEATURE_LEVEL const FeatureLevel = pState->pBackend->dxDevice.FeatureLevel;
3690
3691 /* Most values are taken from:
3692 * https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-intro
3693 *
3694 * Shader values are from
3695 * https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-models
3696 */
3697
3698 switch (idx3dCaps)
3699 {
3700 case SVGA3D_DEVCAP_3D:
3701 *pu32Val = 1;
3702 break;
3703
3704 case SVGA3D_DEVCAP_MAX_LIGHTS:
3705 *pu32Val = SVGA3D_NUM_LIGHTS; /* VGPU9. Not applicable to DX11. */
3706 break;
3707
3708 case SVGA3D_DEVCAP_MAX_TEXTURES:
3709 *pu32Val = SVGA3D_NUM_TEXTURE_UNITS; /* VGPU9. Not applicable to DX11. */
3710 break;
3711
3712 case SVGA3D_DEVCAP_MAX_CLIP_PLANES:
3713 *pu32Val = SVGA3D_NUM_CLIPPLANES;
3714 break;
3715
3716 case SVGA3D_DEVCAP_VERTEX_SHADER_VERSION:
3717 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3718 *pu32Val = SVGA3DVSVERSION_40;
3719 else
3720 *pu32Val = SVGA3DVSVERSION_30;
3721 break;
3722
3723 case SVGA3D_DEVCAP_VERTEX_SHADER:
3724 *pu32Val = 1;
3725 break;
3726
3727 case SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION:
3728 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3729 *pu32Val = SVGA3DPSVERSION_40;
3730 else
3731 *pu32Val = SVGA3DPSVERSION_30;
3732 break;
3733
3734 case SVGA3D_DEVCAP_FRAGMENT_SHADER:
3735 *pu32Val = 1;
3736 break;
3737
3738 case SVGA3D_DEVCAP_MAX_RENDER_TARGETS:
3739 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3740 *pu32Val = 8;
3741 else
3742 *pu32Val = 4;
3743 break;
3744
3745 case SVGA3D_DEVCAP_S23E8_TEXTURES:
3746 case SVGA3D_DEVCAP_S10E5_TEXTURES:
3747 /* Must be obsolete by now; surface format caps specify the same thing. */
3748 break;
3749
3750 case SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND:
3751 /* Obsolete */
3752 break;
3753
3754 /*
3755 * 2. The BUFFER_FORMAT capabilities are deprecated, and they always
3756 * return TRUE. Even on physical hardware that does not support
3757 * these formats natively, the SVGA3D device will provide an emulation
3758 * which should be invisible to the guest OS.
3759 */
3760 case SVGA3D_DEVCAP_D16_BUFFER_FORMAT:
3761 case SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT:
3762 case SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT:
3763 *pu32Val = 1;
3764 break;
3765
3766 case SVGA3D_DEVCAP_QUERY_TYPES:
3767 /* Obsolete */
3768 break;
3769
3770 case SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING:
3771 /* Obsolete */
3772 break;
3773
3774 case SVGA3D_DEVCAP_MAX_POINT_SIZE:
3775 AssertCompile(sizeof(uint32_t) == sizeof(float));
3776 *(float *)pu32Val = 256.0f; /* VGPU9. Not applicable to DX11. */
3777 break;
3778
3779 case SVGA3D_DEVCAP_MAX_SHADER_TEXTURES:
3780 /* Obsolete */
3781 break;
3782
3783 case SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH:
3784 case SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT:
3785 if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
3786 *pu32Val = 16384;
3787 else if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3788 *pu32Val = 8192;
3789 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_3)
3790 *pu32Val = 4096;
3791 else
3792 *pu32Val = 2048;
3793 break;
3794
3795 case SVGA3D_DEVCAP_MAX_VOLUME_EXTENT:
3796 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3797 *pu32Val = 2048;
3798 else
3799 *pu32Val = 256;
3800 break;
3801
3802 case SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT:
3803 if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
3804 *pu32Val = 16384;
3805 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_3)
3806 *pu32Val = 8192;
3807 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
3808 *pu32Val = 2048;
3809 else
3810 *pu32Val = 128;
3811 break;
3812
3813 case SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO:
3814 /* Obsolete */
3815 break;
3816
3817 case SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY:
3818 if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
3819 *pu32Val = D3D11_REQ_MAXANISOTROPY;
3820 else
3821 *pu32Val = 2; // D3D_FL9_1_DEFAULT_MAX_ANISOTROPY;
3822 break;
3823
3824 case SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT:
3825 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3826 *pu32Val = UINT32_MAX;
3827 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
3828 *pu32Val = 1048575; // D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT;
3829 else
3830 *pu32Val = 65535; // D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT;
3831 break;
3832
3833 case SVGA3D_DEVCAP_MAX_VERTEX_INDEX:
3834 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3835 *pu32Val = UINT32_MAX;
3836 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
3837 *pu32Val = 1048575;
3838 else
3839 *pu32Val = 65534;
3840 break;
3841
3842 case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS:
3843 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3844 *pu32Val = UINT32_MAX;
3845 else
3846 *pu32Val = 512;
3847 break;
3848
3849 case SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS:
3850 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3851 *pu32Val = UINT32_MAX;
3852 else
3853 *pu32Val = 512;
3854 break;
3855
3856 case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS:
3857 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3858 *pu32Val = 4096;
3859 else
3860 *pu32Val = 32;
3861 break;
3862
3863 case SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS:
3864 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3865 *pu32Val = 4096;
3866 else
3867 *pu32Val = 32;
3868 break;
3869
3870 case SVGA3D_DEVCAP_TEXTURE_OPS:
3871 /* Obsolete */
3872 break;
3873
3874 case SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8:
3875 case SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8:
3876 case SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10:
3877 case SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5:
3878 case SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5:
3879 case SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4:
3880 case SVGA3D_DEVCAP_SURFACEFMT_R5G6B5:
3881 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16:
3882 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8:
3883 case SVGA3D_DEVCAP_SURFACEFMT_ALPHA8:
3884 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8:
3885 case SVGA3D_DEVCAP_SURFACEFMT_Z_D16:
3886 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8:
3887 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8:
3888 case SVGA3D_DEVCAP_SURFACEFMT_DXT1:
3889 case SVGA3D_DEVCAP_SURFACEFMT_DXT2:
3890 case SVGA3D_DEVCAP_SURFACEFMT_DXT3:
3891 case SVGA3D_DEVCAP_SURFACEFMT_DXT4:
3892 case SVGA3D_DEVCAP_SURFACEFMT_DXT5:
3893 case SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8:
3894 case SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10:
3895 case SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8:
3896 case SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8:
3897 case SVGA3D_DEVCAP_SURFACEFMT_CxV8U8:
3898 case SVGA3D_DEVCAP_SURFACEFMT_R_S10E5:
3899 case SVGA3D_DEVCAP_SURFACEFMT_R_S23E8:
3900 case SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5:
3901 case SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8:
3902 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5:
3903 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8:
3904 case SVGA3D_DEVCAP_SURFACEFMT_V16U16:
3905 case SVGA3D_DEVCAP_SURFACEFMT_G16R16:
3906 case SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16:
3907 case SVGA3D_DEVCAP_SURFACEFMT_UYVY:
3908 case SVGA3D_DEVCAP_SURFACEFMT_YUY2:
3909 case SVGA3D_DEVCAP_SURFACEFMT_NV12:
3910 case SVGA3D_DEVCAP_DEAD10: /* SVGA3D_DEVCAP_SURFACEFMT_AYUV */
3911 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF16:
3912 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF24:
3913 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT:
3914 case SVGA3D_DEVCAP_SURFACEFMT_ATI1:
3915 case SVGA3D_DEVCAP_SURFACEFMT_ATI2:
3916 case SVGA3D_DEVCAP_SURFACEFMT_YV12:
3917 {
3918 SVGA3dSurfaceFormat const enmFormat = vmsvgaDXDevCapSurfaceFmt2Format(idx3dCaps);
3919 rc = vmsvgaDXCheckFormatSupportPreDX(pState, enmFormat, pu32Val);
3920 break;
3921 }
3922
3923 case SVGA3D_DEVCAP_MISSING62:
3924 /* Unused */
3925 break;
3926
3927 case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES:
3928 /* Obsolete */
3929 break;
3930
3931 case SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS:
3932 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3933 *pu32Val = 8;
3934 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_3)
3935 *pu32Val = 4; // D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT
3936 else
3937 *pu32Val = 1; // D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT
3938 break;
3939
3940 case SVGA3D_DEVCAP_DEAD4: /* SVGA3D_DEVCAP_MULTISAMPLE_NONMASKABLESAMPLES */
3941 case SVGA3D_DEVCAP_DEAD5: /* SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES */
3942 *pu32Val = (1 << (2-1)) | (1 << (4-1)) | (1 << (8-1)); /* 2x, 4x, 8x */
3943 break;
3944
3945 case SVGA3D_DEVCAP_DEAD7: /* SVGA3D_DEVCAP_ALPHATOCOVERAGE */
3946 /* Obsolete */
3947 break;
3948
3949 case SVGA3D_DEVCAP_DEAD6: /* SVGA3D_DEVCAP_SUPERSAMPLE */
3950 /* Obsolete */
3951 break;
3952
3953 case SVGA3D_DEVCAP_AUTOGENMIPMAPS:
3954 *pu32Val = 1;
3955 break;
3956
3957 case SVGA3D_DEVCAP_MAX_CONTEXT_IDS:
3958 *pu32Val = SVGA3D_MAX_CONTEXT_IDS;
3959 break;
3960
3961 case SVGA3D_DEVCAP_MAX_SURFACE_IDS:
3962 *pu32Val = SVGA3D_MAX_SURFACE_IDS;
3963 break;
3964
3965 case SVGA3D_DEVCAP_DEAD1:
3966 /* Obsolete */
3967 break;
3968
3969 case SVGA3D_DEVCAP_DEAD8: /* SVGA3D_DEVCAP_VIDEO_DECODE */
3970 /* Obsolete */
3971 break;
3972
3973 case SVGA3D_DEVCAP_DEAD9: /* SVGA3D_DEVCAP_VIDEO_PROCESS */
3974 /* Obsolete */
3975 break;
3976
3977 case SVGA3D_DEVCAP_LINE_AA:
3978 *pu32Val = 1;
3979 break;
3980
3981 case SVGA3D_DEVCAP_LINE_STIPPLE:
3982 *pu32Val = 0; /* DX11 does not seem to support this directly. */
3983 break;
3984
3985 case SVGA3D_DEVCAP_MAX_LINE_WIDTH:
3986 AssertCompile(sizeof(uint32_t) == sizeof(float));
3987 *(float *)pu32Val = 1.0f;
3988 break;
3989
3990 case SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH:
3991 AssertCompile(sizeof(uint32_t) == sizeof(float));
3992 *(float *)pu32Val = 1.0f;
3993 break;
3994
3995 case SVGA3D_DEVCAP_DEAD3: /* Old SVGA3D_DEVCAP_LOGICOPS */
3996 /* Deprecated. */
3997 AssertCompile(SVGA3D_DEVCAP_DEAD3 == 92); /* Newer SVGA headers redefine this. */
3998 break;
3999
4000 case SVGA3D_DEVCAP_TS_COLOR_KEY:
4001 *pu32Val = 0; /* DX11 does not seem to support this directly. */
4002 break;
4003
4004 case SVGA3D_DEVCAP_DEAD2:
4005 break;
4006
4007 case SVGA3D_DEVCAP_DXCONTEXT:
4008 *pu32Val = 1;
4009 break;
4010
4011 case SVGA3D_DEVCAP_DEAD11: /* SVGA3D_DEVCAP_MAX_TEXTURE_ARRAY_SIZE */
4012 *pu32Val = D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
4013 break;
4014
4015 case SVGA3D_DEVCAP_DX_MAX_VERTEXBUFFERS:
4016 *pu32Val = D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT;
4017 break;
4018
4019 case SVGA3D_DEVCAP_DX_MAX_CONSTANT_BUFFERS:
4020 *pu32Val = D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT;
4021 break;
4022
4023 case SVGA3D_DEVCAP_DX_PROVOKING_VERTEX:
4024 *pu32Val = 0; /* boolean */
4025 break;
4026
4027 case SVGA3D_DEVCAP_DXFMT_X8R8G8B8:
4028 case SVGA3D_DEVCAP_DXFMT_A8R8G8B8:
4029 case SVGA3D_DEVCAP_DXFMT_R5G6B5:
4030 case SVGA3D_DEVCAP_DXFMT_X1R5G5B5:
4031 case SVGA3D_DEVCAP_DXFMT_A1R5G5B5:
4032 case SVGA3D_DEVCAP_DXFMT_A4R4G4B4:
4033 case SVGA3D_DEVCAP_DXFMT_Z_D32:
4034 case SVGA3D_DEVCAP_DXFMT_Z_D16:
4035 case SVGA3D_DEVCAP_DXFMT_Z_D24S8:
4036 case SVGA3D_DEVCAP_DXFMT_Z_D15S1:
4037 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8:
4038 case SVGA3D_DEVCAP_DXFMT_LUMINANCE4_ALPHA4:
4039 case SVGA3D_DEVCAP_DXFMT_LUMINANCE16:
4040 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8_ALPHA8:
4041 case SVGA3D_DEVCAP_DXFMT_DXT1:
4042 case SVGA3D_DEVCAP_DXFMT_DXT2:
4043 case SVGA3D_DEVCAP_DXFMT_DXT3:
4044 case SVGA3D_DEVCAP_DXFMT_DXT4:
4045 case SVGA3D_DEVCAP_DXFMT_DXT5:
4046 case SVGA3D_DEVCAP_DXFMT_BUMPU8V8:
4047 case SVGA3D_DEVCAP_DXFMT_BUMPL6V5U5:
4048 case SVGA3D_DEVCAP_DXFMT_BUMPX8L8V8U8:
4049 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD1:
4050 case SVGA3D_DEVCAP_DXFMT_ARGB_S10E5:
4051 case SVGA3D_DEVCAP_DXFMT_ARGB_S23E8:
4052 case SVGA3D_DEVCAP_DXFMT_A2R10G10B10:
4053 case SVGA3D_DEVCAP_DXFMT_V8U8:
4054 case SVGA3D_DEVCAP_DXFMT_Q8W8V8U8:
4055 case SVGA3D_DEVCAP_DXFMT_CxV8U8:
4056 case SVGA3D_DEVCAP_DXFMT_X8L8V8U8:
4057 case SVGA3D_DEVCAP_DXFMT_A2W10V10U10:
4058 case SVGA3D_DEVCAP_DXFMT_ALPHA8:
4059 case SVGA3D_DEVCAP_DXFMT_R_S10E5:
4060 case SVGA3D_DEVCAP_DXFMT_R_S23E8:
4061 case SVGA3D_DEVCAP_DXFMT_RG_S10E5:
4062 case SVGA3D_DEVCAP_DXFMT_RG_S23E8:
4063 case SVGA3D_DEVCAP_DXFMT_BUFFER:
4064 case SVGA3D_DEVCAP_DXFMT_Z_D24X8:
4065 case SVGA3D_DEVCAP_DXFMT_V16U16:
4066 case SVGA3D_DEVCAP_DXFMT_G16R16:
4067 case SVGA3D_DEVCAP_DXFMT_A16B16G16R16:
4068 case SVGA3D_DEVCAP_DXFMT_UYVY:
4069 case SVGA3D_DEVCAP_DXFMT_YUY2:
4070 case SVGA3D_DEVCAP_DXFMT_NV12:
4071 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD2: /* SVGA3D_DEVCAP_DXFMT_AYUV */
4072 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_TYPELESS:
4073 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_UINT:
4074 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_SINT:
4075 case SVGA3D_DEVCAP_DXFMT_R32G32B32_TYPELESS:
4076 case SVGA3D_DEVCAP_DXFMT_R32G32B32_FLOAT:
4077 case SVGA3D_DEVCAP_DXFMT_R32G32B32_UINT:
4078 case SVGA3D_DEVCAP_DXFMT_R32G32B32_SINT:
4079 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_TYPELESS:
4080 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UINT:
4081 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SNORM:
4082 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SINT:
4083 case SVGA3D_DEVCAP_DXFMT_R32G32_TYPELESS:
4084 case SVGA3D_DEVCAP_DXFMT_R32G32_UINT:
4085 case SVGA3D_DEVCAP_DXFMT_R32G32_SINT:
4086 case SVGA3D_DEVCAP_DXFMT_R32G8X24_TYPELESS:
4087 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT_S8X24_UINT:
4088 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT_X8X24:
4089 case SVGA3D_DEVCAP_DXFMT_X32_G8X24_UINT:
4090 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_TYPELESS:
4091 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UINT:
4092 case SVGA3D_DEVCAP_DXFMT_R11G11B10_FLOAT:
4093 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_TYPELESS:
4094 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM:
4095 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM_SRGB:
4096 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UINT:
4097 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SINT:
4098 case SVGA3D_DEVCAP_DXFMT_R16G16_TYPELESS:
4099 case SVGA3D_DEVCAP_DXFMT_R16G16_UINT:
4100 case SVGA3D_DEVCAP_DXFMT_R16G16_SINT:
4101 case SVGA3D_DEVCAP_DXFMT_R32_TYPELESS:
4102 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT:
4103 case SVGA3D_DEVCAP_DXFMT_R32_UINT:
4104 case SVGA3D_DEVCAP_DXFMT_R32_SINT:
4105 case SVGA3D_DEVCAP_DXFMT_R24G8_TYPELESS:
4106 case SVGA3D_DEVCAP_DXFMT_D24_UNORM_S8_UINT:
4107 case SVGA3D_DEVCAP_DXFMT_R24_UNORM_X8:
4108 case SVGA3D_DEVCAP_DXFMT_X24_G8_UINT:
4109 case SVGA3D_DEVCAP_DXFMT_R8G8_TYPELESS:
4110 case SVGA3D_DEVCAP_DXFMT_R8G8_UNORM:
4111 case SVGA3D_DEVCAP_DXFMT_R8G8_UINT:
4112 case SVGA3D_DEVCAP_DXFMT_R8G8_SINT:
4113 case SVGA3D_DEVCAP_DXFMT_R16_TYPELESS:
4114 case SVGA3D_DEVCAP_DXFMT_R16_UNORM:
4115 case SVGA3D_DEVCAP_DXFMT_R16_UINT:
4116 case SVGA3D_DEVCAP_DXFMT_R16_SNORM:
4117 case SVGA3D_DEVCAP_DXFMT_R16_SINT:
4118 case SVGA3D_DEVCAP_DXFMT_R8_TYPELESS:
4119 case SVGA3D_DEVCAP_DXFMT_R8_UNORM:
4120 case SVGA3D_DEVCAP_DXFMT_R8_UINT:
4121 case SVGA3D_DEVCAP_DXFMT_R8_SNORM:
4122 case SVGA3D_DEVCAP_DXFMT_R8_SINT:
4123 case SVGA3D_DEVCAP_DXFMT_P8:
4124 case SVGA3D_DEVCAP_DXFMT_R9G9B9E5_SHAREDEXP:
4125 case SVGA3D_DEVCAP_DXFMT_R8G8_B8G8_UNORM:
4126 case SVGA3D_DEVCAP_DXFMT_G8R8_G8B8_UNORM:
4127 case SVGA3D_DEVCAP_DXFMT_BC1_TYPELESS:
4128 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM_SRGB:
4129 case SVGA3D_DEVCAP_DXFMT_BC2_TYPELESS:
4130 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM_SRGB:
4131 case SVGA3D_DEVCAP_DXFMT_BC3_TYPELESS:
4132 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM_SRGB:
4133 case SVGA3D_DEVCAP_DXFMT_BC4_TYPELESS:
4134 case SVGA3D_DEVCAP_DXFMT_ATI1:
4135 case SVGA3D_DEVCAP_DXFMT_BC4_SNORM:
4136 case SVGA3D_DEVCAP_DXFMT_BC5_TYPELESS:
4137 case SVGA3D_DEVCAP_DXFMT_ATI2:
4138 case SVGA3D_DEVCAP_DXFMT_BC5_SNORM:
4139 case SVGA3D_DEVCAP_DXFMT_R10G10B10_XR_BIAS_A2_UNORM:
4140 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_TYPELESS:
4141 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM_SRGB:
4142 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_TYPELESS:
4143 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM_SRGB:
4144 case SVGA3D_DEVCAP_DXFMT_Z_DF16:
4145 case SVGA3D_DEVCAP_DXFMT_Z_DF24:
4146 case SVGA3D_DEVCAP_DXFMT_Z_D24S8_INT:
4147 case SVGA3D_DEVCAP_DXFMT_YV12:
4148 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_FLOAT:
4149 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_FLOAT:
4150 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UNORM:
4151 case SVGA3D_DEVCAP_DXFMT_R32G32_FLOAT:
4152 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UNORM:
4153 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SNORM:
4154 case SVGA3D_DEVCAP_DXFMT_R16G16_FLOAT:
4155 case SVGA3D_DEVCAP_DXFMT_R16G16_UNORM:
4156 case SVGA3D_DEVCAP_DXFMT_R16G16_SNORM:
4157 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT:
4158 case SVGA3D_DEVCAP_DXFMT_R8G8_SNORM:
4159 case SVGA3D_DEVCAP_DXFMT_R16_FLOAT:
4160 case SVGA3D_DEVCAP_DXFMT_D16_UNORM:
4161 case SVGA3D_DEVCAP_DXFMT_A8_UNORM:
4162 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM:
4163 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM:
4164 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM:
4165 case SVGA3D_DEVCAP_DXFMT_B5G6R5_UNORM:
4166 case SVGA3D_DEVCAP_DXFMT_B5G5R5A1_UNORM:
4167 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM:
4168 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM:
4169 case SVGA3D_DEVCAP_DXFMT_BC4_UNORM:
4170 case SVGA3D_DEVCAP_DXFMT_BC5_UNORM:
4171 case SVGA3D_DEVCAP_DXFMT_BC6H_TYPELESS:
4172 case SVGA3D_DEVCAP_DXFMT_BC6H_UF16:
4173 case SVGA3D_DEVCAP_DXFMT_BC6H_SF16:
4174 case SVGA3D_DEVCAP_DXFMT_BC7_TYPELESS:
4175 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM:
4176 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM_SRGB:
4177 {
4178 SVGA3dSurfaceFormat const enmFormat = vmsvgaDXDevCapDxfmt2Format(idx3dCaps);
4179 rc = vmsvgaDXCheckFormatSupport(pState, enmFormat, pu32Val);
4180 break;
4181 }
4182
4183 case SVGA3D_DEVCAP_SM41:
4184 *pu32Val = 0; /* boolean */
4185 break;
4186
4187 case SVGA3D_DEVCAP_MULTISAMPLE_2X:
4188 *pu32Val = 0; /* boolean */
4189 break;
4190
4191 case SVGA3D_DEVCAP_MULTISAMPLE_4X:
4192 *pu32Val = 0; /* boolean */
4193 break;
4194
4195 case SVGA3D_DEVCAP_MS_FULL_QUALITY:
4196 *pu32Val = 0; /* boolean */
4197 break;
4198
4199 case SVGA3D_DEVCAP_LOGICOPS:
4200 AssertCompile(SVGA3D_DEVCAP_LOGICOPS == 248);
4201 *pu32Val = 0; /* boolean */
4202 break;
4203
4204 case SVGA3D_DEVCAP_LOGIC_BLENDOPS:
4205 *pu32Val = 0; /* boolean */
4206 break;
4207
4208 case SVGA3D_DEVCAP_RESERVED_1:
4209 break;
4210
4211 case SVGA3D_DEVCAP_RESERVED_2:
4212 break;
4213
4214 case SVGA3D_DEVCAP_SM5:
4215 *pu32Val = 0; /* boolean */
4216 break;
4217
4218 case SVGA3D_DEVCAP_MULTISAMPLE_8X:
4219 *pu32Val = 0; /* boolean */
4220 break;
4221
4222 case SVGA3D_DEVCAP_MAX:
4223 case SVGA3D_DEVCAP_INVALID:
4224 rc = VERR_NOT_SUPPORTED;
4225 break;
4226 }
4227
4228 return rc;
4229}
4230
4231
4232static DECLCALLBACK(int) vmsvga3dBackChangeMode(PVGASTATECC pThisCC)
4233{
4234 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4235 AssertReturn(pState, VERR_INVALID_STATE);
4236
4237 return VINF_SUCCESS;
4238}
4239
4240
4241static DECLCALLBACK(int) vmsvga3dBackSurfaceCopy(PVGASTATECC pThisCC, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src,
4242 uint32_t cCopyBoxes, SVGA3dCopyBox *pBox)
4243{
4244 RT_NOREF(cCopyBoxes, pBox);
4245
4246 LogFunc(("src sid %d -> dst sid %d\n", src.sid, dest.sid));
4247
4248 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4249 AssertReturn(pState, VERR_INVALID_STATE);
4250
4251 PVMSVGA3DBACKEND pBackend = pState->pBackend;
4252
4253 PVMSVGA3DSURFACE pSrcSurface;
4254 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, src.sid, &pSrcSurface);
4255 AssertRCReturn(rc, rc);
4256
4257 PVMSVGA3DSURFACE pDstSurface;
4258 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, dest.sid, &pDstSurface);
4259 AssertRCReturn(rc, rc);
4260
4261 LogFunc(("src%s cid %d -> dst%s cid %d\n",
4262 pSrcSurface->pBackendSurface ? "" : " sysmem",
4263 pSrcSurface ? pSrcSurface->idAssociatedContext : SVGA_ID_INVALID,
4264 pDstSurface->pBackendSurface ? "" : " sysmem",
4265 pDstSurface ? pDstSurface->idAssociatedContext : SVGA_ID_INVALID));
4266
4267 //DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
4268 //AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
4269
4270 if (pSrcSurface->pBackendSurface)
4271 {
4272 if (pDstSurface->pBackendSurface == NULL)
4273 {
4274 /* Create the target if it can be used as a device context shared resource (render or screen target). */
4275 if (pBackend->fSingleDevice || dxIsSurfaceShareable(pDstSurface))
4276 {
4277 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, NULL, pDstSurface);
4278 AssertRCReturn(rc, rc);
4279 }
4280 }
4281
4282 if (pDstSurface->pBackendSurface)
4283 {
4284 /* Surface -> Surface. */
4285 /* Expect both of them to be shared surfaces created by the backend context. */
4286 Assert(pSrcSurface->idAssociatedContext == DX_CID_BACKEND && pDstSurface->idAssociatedContext == DX_CID_BACKEND);
4287
4288 /* Wait for the source surface to finish drawing. */
4289 dxSurfaceWait(pState, pSrcSurface, DX_CID_BACKEND);
4290
4291 DXDEVICE *pDXDevice = &pBackend->dxDevice;
4292
4293 /* Clip the box. */
4294 PVMSVGA3DMIPMAPLEVEL pSrcMipLevel;
4295 rc = vmsvga3dMipmapLevel(pSrcSurface, src.face, src.mipmap, &pSrcMipLevel);
4296 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
4297
4298 PVMSVGA3DMIPMAPLEVEL pDstMipLevel;
4299 rc = vmsvga3dMipmapLevel(pDstSurface, dest.face, dest.mipmap, &pDstMipLevel);
4300 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
4301
4302 SVGA3dCopyBox clipBox = *pBox;
4303 vmsvgaR3ClipCopyBox(&pSrcMipLevel->mipmapSize, &pDstMipLevel->mipmapSize, &clipBox);
4304
4305 UINT DstSubresource = vmsvga3dCalcSubresource(dest.mipmap, dest.face, pDstSurface->cLevels);
4306 UINT DstX = clipBox.x;
4307 UINT DstY = clipBox.y;
4308 UINT DstZ = clipBox.z;
4309
4310 UINT SrcSubresource = vmsvga3dCalcSubresource(src.mipmap, src.face, pSrcSurface->cLevels);
4311 D3D11_BOX SrcBox;
4312 SrcBox.left = clipBox.srcx;
4313 SrcBox.top = clipBox.srcy;
4314 SrcBox.front = clipBox.srcz;
4315 SrcBox.right = clipBox.srcx + clipBox.w;
4316 SrcBox.bottom = clipBox.srcy + clipBox.h;
4317 SrcBox.back = clipBox.srcz + clipBox.d;
4318
4319 Assert(cCopyBoxes == 1); /** @todo */
4320
4321 ID3D11Resource *pDstResource;
4322 ID3D11Resource *pSrcResource;
4323 pDstResource = dxResource(pState, pDstSurface, NULL);
4324 pSrcResource = dxResource(pState, pSrcSurface, NULL);
4325
4326 pDXDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
4327 pSrcResource, SrcSubresource, &SrcBox);
4328
4329 pDstSurface->pBackendSurface->cidDrawing = DX_CID_BACKEND;
4330 }
4331 else
4332 {
4333 /* Surface -> Memory. */
4334 AssertFailed(); /** @todo implement */
4335 }
4336 }
4337 else
4338 {
4339 /* Memory -> Surface. */
4340 AssertFailed(); /** @todo implement */
4341 }
4342
4343 return rc;
4344}
4345
4346
4347static DECLCALLBACK(void) vmsvga3dBackUpdateHostScreenViewport(PVGASTATECC pThisCC, uint32_t idScreen, VMSVGAVIEWPORT const *pOldViewport)
4348{
4349 RT_NOREF(pThisCC, idScreen, pOldViewport);
4350 /** @todo Scroll the screen content without requiring the guest to redraw. */
4351}
4352
4353
4354static DECLCALLBACK(int) vmsvga3dBackSurfaceUpdateHeapBuffers(PVGASTATECC pThisCC, PVMSVGA3DSURFACE pSurface)
4355{
4356 /** @todo */
4357 RT_NOREF(pThisCC, pSurface);
4358 return VERR_NOT_IMPLEMENTED;
4359}
4360
4361
4362#if 0 /*unused*/
4363/**
4364 * Create a new 3d context
4365 *
4366 * @returns VBox status code.
4367 * @param pThisCC The VGA/VMSVGA state for ring-3.
4368 * @param cid Context id
4369 */
4370static DECLCALLBACK(int) vmsvga3dBackContextDefine(PVGASTATECC pThisCC, uint32_t cid)
4371{
4372 RT_NOREF(cid);
4373
4374 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4375 AssertReturn(pState, VERR_INVALID_STATE);
4376
4377 AssertFailed();
4378 return VERR_NOT_IMPLEMENTED;
4379}
4380
4381
4382/**
4383 * Destroy an existing 3d context
4384 *
4385 * @returns VBox status code.
4386 * @param pThisCC The VGA/VMSVGA state for ring-3.
4387 * @param cid Context id
4388 */
4389static DECLCALLBACK(int) vmsvga3dBackContextDestroy(PVGASTATECC pThisCC, uint32_t cid)
4390{
4391 RT_NOREF(cid);
4392
4393 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4394 AssertReturn(pState, VERR_INVALID_STATE);
4395
4396 AssertFailed();
4397 return VINF_SUCCESS;
4398}
4399
4400
4401static DECLCALLBACK(int) vmsvga3dBackSetTransform(PVGASTATECC pThisCC, uint32_t cid, SVGA3dTransformType type, float matrix[16])
4402{
4403 RT_NOREF(cid, type, matrix);
4404
4405 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4406 AssertReturn(pState, VERR_INVALID_STATE);
4407
4408 AssertFailed();
4409 return VINF_SUCCESS;
4410}
4411
4412
4413static DECLCALLBACK(int) vmsvga3dBackSetZRange(PVGASTATECC pThisCC, uint32_t cid, SVGA3dZRange zRange)
4414{
4415 RT_NOREF(cid, zRange);
4416
4417 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4418 AssertReturn(pState, VERR_INVALID_STATE);
4419
4420 AssertFailed();
4421 return VINF_SUCCESS;
4422}
4423
4424
4425static DECLCALLBACK(int) vmsvga3dBackSetRenderState(PVGASTATECC pThisCC, uint32_t cid, uint32_t cRenderStates, SVGA3dRenderState *pRenderState)
4426{
4427 RT_NOREF(cid, cRenderStates, pRenderState);
4428
4429 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4430 AssertReturn(pState, VERR_INVALID_STATE);
4431
4432 AssertFailed();
4433 return VINF_SUCCESS;
4434}
4435
4436
4437static DECLCALLBACK(int) vmsvga3dBackSetRenderTarget(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRenderTargetType type, SVGA3dSurfaceImageId target)
4438{
4439 RT_NOREF(cid, type, target);
4440
4441 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4442 AssertReturn(pState, VERR_INVALID_STATE);
4443
4444 AssertFailed();
4445 return VINF_SUCCESS;
4446}
4447
4448
4449static DECLCALLBACK(int) vmsvga3dBackSetTextureState(PVGASTATECC pThisCC, uint32_t cid, uint32_t cTextureStates, SVGA3dTextureState *pTextureState)
4450{
4451 RT_NOREF(cid, cTextureStates, pTextureState);
4452
4453 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4454 AssertReturn(pState, VERR_INVALID_STATE);
4455
4456 AssertFailed();
4457 return VINF_SUCCESS;
4458}
4459
4460
4461static DECLCALLBACK(int) vmsvga3dBackSetMaterial(PVGASTATECC pThisCC, uint32_t cid, SVGA3dFace face, SVGA3dMaterial *pMaterial)
4462{
4463 RT_NOREF(cid, face, pMaterial);
4464
4465 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4466 AssertReturn(pState, VERR_INVALID_STATE);
4467
4468 AssertFailed();
4469 return VINF_SUCCESS;
4470}
4471
4472
4473static DECLCALLBACK(int) vmsvga3dBackSetLightData(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, SVGA3dLightData *pData)
4474{
4475 RT_NOREF(cid, index, pData);
4476
4477 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4478 AssertReturn(pState, VERR_INVALID_STATE);
4479
4480 AssertFailed();
4481 return VINF_SUCCESS;
4482}
4483
4484
4485static DECLCALLBACK(int) vmsvga3dBackSetLightEnabled(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, uint32_t enabled)
4486{
4487 RT_NOREF(cid, index, enabled);
4488
4489 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4490 AssertReturn(pState, VERR_INVALID_STATE);
4491
4492 AssertFailed();
4493 return VINF_SUCCESS;
4494}
4495
4496
4497static DECLCALLBACK(int) vmsvga3dBackSetViewPort(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRect *pRect)
4498{
4499 RT_NOREF(cid, pRect);
4500
4501 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4502 AssertReturn(pState, VERR_INVALID_STATE);
4503
4504 AssertFailed();
4505 return VINF_SUCCESS;
4506}
4507
4508
4509static DECLCALLBACK(int) vmsvga3dBackSetClipPlane(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, float plane[4])
4510{
4511 RT_NOREF(cid, index, plane);
4512
4513 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4514 AssertReturn(pState, VERR_INVALID_STATE);
4515
4516 AssertFailed();
4517 return VINF_SUCCESS;
4518}
4519
4520
4521static DECLCALLBACK(int) vmsvga3dBackCommandClear(PVGASTATECC pThisCC, uint32_t cid, SVGA3dClearFlag clearFlag, uint32_t color, float depth,
4522 uint32_t stencil, uint32_t cRects, SVGA3dRect *pRect)
4523{
4524 /* From SVGA3D_BeginClear comments:
4525 *
4526 * Clear is not affected by clipping, depth test, or other
4527 * render state which affects the fragment pipeline.
4528 *
4529 * Therefore this code must ignore the current scissor rect.
4530 */
4531
4532 RT_NOREF(cid, clearFlag, color, depth, stencil, cRects, pRect);
4533
4534 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4535 AssertReturn(pState, VERR_INVALID_STATE);
4536
4537 AssertFailed();
4538 return VINF_SUCCESS;
4539}
4540
4541
4542static DECLCALLBACK(int) vmsvga3dBackDrawPrimitives(PVGASTATECC pThisCC, uint32_t cid, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl,
4543 uint32_t numRanges, SVGA3dPrimitiveRange *pRange,
4544 uint32_t cVertexDivisor, SVGA3dVertexDivisor *pVertexDivisor)
4545{
4546 RT_NOREF(cid, numVertexDecls, pVertexDecl, numRanges, pRange, cVertexDivisor, pVertexDivisor);
4547
4548 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4549 AssertReturn(pState, VERR_INVALID_STATE);
4550
4551 AssertFailed();
4552 return VINF_SUCCESS;
4553}
4554
4555
4556static DECLCALLBACK(int) vmsvga3dBackSetScissorRect(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRect *pRect)
4557{
4558 RT_NOREF(cid, pRect);
4559
4560 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4561 AssertReturn(pState, VERR_INVALID_STATE);
4562
4563 AssertFailed();
4564 return VINF_SUCCESS;
4565}
4566
4567
4568static DECLCALLBACK(int) vmsvga3dBackGenerateMipmaps(PVGASTATECC pThisCC, uint32_t sid, SVGA3dTextureFilter filter)
4569{
4570 RT_NOREF(sid, filter);
4571
4572 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4573 AssertReturn(pState, VERR_INVALID_STATE);
4574
4575 AssertFailed();
4576 return VINF_SUCCESS;
4577}
4578
4579
4580static DECLCALLBACK(int) vmsvga3dBackShaderDefine(PVGASTATECC pThisCC, uint32_t cid, uint32_t shid, SVGA3dShaderType type,
4581 uint32_t cbData, uint32_t *pShaderData)
4582{
4583 RT_NOREF(cid, shid, type, cbData, pShaderData);
4584
4585 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4586 AssertReturn(pState, VERR_INVALID_STATE);
4587
4588 AssertFailed();
4589 return VINF_SUCCESS;
4590}
4591
4592
4593static DECLCALLBACK(int) vmsvga3dBackShaderDestroy(PVGASTATECC pThisCC, uint32_t cid, uint32_t shid, SVGA3dShaderType type)
4594{
4595 RT_NOREF(cid, shid, type);
4596
4597 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4598 AssertReturn(pState, VERR_INVALID_STATE);
4599
4600 AssertFailed();
4601 return VINF_SUCCESS;
4602}
4603
4604
4605static DECLCALLBACK(int) vmsvga3dBackShaderSet(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext, uint32_t cid, SVGA3dShaderType type, uint32_t shid)
4606{
4607 RT_NOREF(pContext, cid, type, shid);
4608
4609 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4610 AssertReturn(pState, VERR_INVALID_STATE);
4611
4612 AssertFailed();
4613 return VINF_SUCCESS;
4614}
4615
4616
4617static DECLCALLBACK(int) vmsvga3dBackShaderSetConst(PVGASTATECC pThisCC, uint32_t cid, uint32_t reg, SVGA3dShaderType type,
4618 SVGA3dShaderConstType ctype, uint32_t cRegisters, uint32_t *pValues)
4619{
4620 RT_NOREF(cid, reg, type, ctype, cRegisters, pValues);
4621
4622 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4623 AssertReturn(pState, VERR_INVALID_STATE);
4624
4625 AssertFailed();
4626 return VINF_SUCCESS;
4627}
4628#endif
4629
4630
4631/**
4632 * Destroy backend specific surface bits (part of SVGA_3D_CMD_SURFACE_DESTROY).
4633 *
4634 * @param pThisCC The device context.
4635 * @param pSurface The surface being destroyed.
4636 */
4637static DECLCALLBACK(void) vmsvga3dBackSurfaceDestroy(PVGASTATECC pThisCC, PVMSVGA3DSURFACE pSurface)
4638{
4639 RT_NOREF(pThisCC);
4640
4641 /* The caller should not use the function for system memory surfaces. */
4642 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
4643 if (!pBackendSurface)
4644 return;
4645 pSurface->pBackendSurface = NULL;
4646
4647 LogFunc(("sid=%u\n", pSurface->id));
4648
4649 /* If any views have been created for this resource, then also release them. */
4650 DXVIEW *pIter, *pNext;
4651 RTListForEachSafe(&pBackendSurface->u2.Texture.listView, pIter, pNext, DXVIEW, nodeSurfaceView)
4652 {
4653 LogFunc(("pIter=%p, pNext=%p\n", pIter, pNext));
4654 dxViewDestroy(pIter);
4655 }
4656
4657 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
4658 {
4659 D3D_RELEASE(pBackendSurface->pStagingTexture);
4660 D3D_RELEASE(pBackendSurface->pDynamicTexture);
4661 D3D_RELEASE(pBackendSurface->u.pTexture2D);
4662 }
4663 else if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
4664 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_CUBE)
4665 {
4666 D3D_RELEASE(pBackendSurface->pStagingTexture);
4667 D3D_RELEASE(pBackendSurface->pDynamicTexture);
4668 D3D_RELEASE(pBackendSurface->u.pTexture2D);
4669 }
4670 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
4671 {
4672 D3D_RELEASE(pBackendSurface->pStagingTexture3D);
4673 D3D_RELEASE(pBackendSurface->pDynamicTexture3D);
4674 D3D_RELEASE(pBackendSurface->u.pTexture3D);
4675 }
4676 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
4677 {
4678 D3D_RELEASE(pBackendSurface->u.pBuffer);
4679 }
4680 else
4681 {
4682 AssertFailed();
4683 }
4684
4685 RTMemFree(pBackendSurface);
4686
4687 /* No context has created the surface, because the surface does not exist anymore. */
4688 pSurface->idAssociatedContext = SVGA_ID_INVALID;
4689}
4690
4691
4692static DECLCALLBACK(void) vmsvga3dBackSurfaceInvalidateImage(PVGASTATECC pThisCC, PVMSVGA3DSURFACE pSurface, uint32_t uFace, uint32_t uMipmap)
4693{
4694 RT_NOREF(pThisCC, uFace, uMipmap);
4695
4696 /* The caller should not use the function for system memory surfaces. */
4697 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
4698 if (!pBackendSurface)
4699 return;
4700
4701 LogFunc(("sid=%u\n", pSurface->id));
4702
4703 /* The guest uses this to invalidate a buffer. */
4704 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
4705 {
4706 Assert(uFace == 0 && uMipmap == 0); /* The caller ensures this. */
4707 /** @todo This causes flickering when a buffer is invalidated and re-created right before a draw call. */
4708 //vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
4709 }
4710 else
4711 {
4712 /** @todo Delete views that have been created for this mipmap.
4713 * For now just delete all views, they will be recte=reated if necessary.
4714 */
4715 ASSERT_GUEST_FAILED();
4716 DXVIEW *pIter, *pNext;
4717 RTListForEachSafe(&pBackendSurface->u2.Texture.listView, pIter, pNext, DXVIEW, nodeSurfaceView)
4718 {
4719 dxViewDestroy(pIter);
4720 }
4721 }
4722}
4723
4724
4725/**
4726 * Backend worker for implementing SVGA_3D_CMD_SURFACE_STRETCHBLT.
4727 *
4728 * @returns VBox status code.
4729 * @param pThis The VGA device instance.
4730 * @param pState The VMSVGA3d state.
4731 * @param pDstSurface The destination host surface.
4732 * @param uDstFace The destination face (valid).
4733 * @param uDstMipmap The destination mipmap level (valid).
4734 * @param pDstBox The destination box.
4735 * @param pSrcSurface The source host surface.
4736 * @param uSrcFace The destination face (valid).
4737 * @param uSrcMipmap The source mimap level (valid).
4738 * @param pSrcBox The source box.
4739 * @param enmMode The strecht blt mode .
4740 * @param pContext The VMSVGA3d context (already current for OGL).
4741 */
4742static DECLCALLBACK(int) vmsvga3dBackSurfaceStretchBlt(PVGASTATE pThis, PVMSVGA3DSTATE pState,
4743 PVMSVGA3DSURFACE pDstSurface, uint32_t uDstFace, uint32_t uDstMipmap, SVGA3dBox const *pDstBox,
4744 PVMSVGA3DSURFACE pSrcSurface, uint32_t uSrcFace, uint32_t uSrcMipmap, SVGA3dBox const *pSrcBox,
4745 SVGA3dStretchBltMode enmMode, PVMSVGA3DCONTEXT pContext)
4746{
4747 RT_NOREF(pThis, pState, pDstSurface, uDstFace, uDstMipmap, pDstBox,
4748 pSrcSurface, uSrcFace, uSrcMipmap, pSrcBox, enmMode, pContext);
4749
4750 AssertFailed();
4751 return VINF_SUCCESS;
4752}
4753
4754
4755/**
4756 * Backend worker for implementing SVGA_3D_CMD_SURFACE_DMA that copies one box.
4757 *
4758 * @returns Failure status code or @a rc.
4759 * @param pThis The shared VGA/VMSVGA instance data.
4760 * @param pThisCC The VGA/VMSVGA state for ring-3.
4761 * @param pState The VMSVGA3d state.
4762 * @param pSurface The host surface.
4763 * @param pMipLevel Mipmap level. The caller knows it already.
4764 * @param uHostFace The host face (valid).
4765 * @param uHostMipmap The host mipmap level (valid).
4766 * @param GuestPtr The guest pointer.
4767 * @param cbGuestPitch The guest pitch.
4768 * @param transfer The transfer direction.
4769 * @param pBox The box to copy (clipped, valid, except for guest's srcx, srcy, srcz).
4770 * @param pContext The context (for OpenGL).
4771 * @param rc The current rc for all boxes.
4772 * @param iBox The current box number (for Direct 3D).
4773 */
4774static DECLCALLBACK(int) vmsvga3dBackSurfaceDMACopyBox(PVGASTATE pThis, PVGASTATECC pThisCC, PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface,
4775 PVMSVGA3DMIPMAPLEVEL pMipLevel, uint32_t uHostFace, uint32_t uHostMipmap,
4776 SVGAGuestPtr GuestPtr, uint32_t cbGuestPitch, SVGA3dTransferType transfer,
4777 SVGA3dCopyBox const *pBox, PVMSVGA3DCONTEXT pContext, int rc, int iBox)
4778{
4779 RT_NOREF(pState, pMipLevel, pContext, iBox);
4780
4781 /* The called should not use the function for system memory surfaces. */
4782 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
4783 AssertReturn(pBackendSurface, VERR_INVALID_PARAMETER);
4784
4785 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
4786 {
4787 /** @todo This is generic code and should be in DevVGA-SVGA3d.cpp for backends which support Map/Unmap. */
4788 AssertReturn(uHostFace == 0 && uHostMipmap == 0, VERR_INVALID_PARAMETER);
4789
4790 uint32_t const u32GuestBlockX = pBox->srcx / pSurface->cxBlock;
4791 uint32_t const u32GuestBlockY = pBox->srcy / pSurface->cyBlock;
4792 Assert(u32GuestBlockX * pSurface->cxBlock == pBox->srcx);
4793 Assert(u32GuestBlockY * pSurface->cyBlock == pBox->srcy);
4794 uint32_t const cBlocksX = (pBox->w + pSurface->cxBlock - 1) / pSurface->cxBlock;
4795 uint32_t const cBlocksY = (pBox->h + pSurface->cyBlock - 1) / pSurface->cyBlock;
4796 AssertMsgReturn(cBlocksX && cBlocksY, ("Empty box %dx%d\n", pBox->w, pBox->h), VERR_INTERNAL_ERROR);
4797
4798 /* vmsvgaR3GmrTransfer verifies uGuestOffset.
4799 * srcx(u32GuestBlockX) and srcy(u32GuestBlockY) have been verified in vmsvga3dSurfaceDMA
4800 * to not cause 32 bit overflow when multiplied by cbBlock and cbGuestPitch.
4801 */
4802 uint64_t const uGuestOffset = u32GuestBlockX * pSurface->cbBlock + u32GuestBlockY * cbGuestPitch;
4803 AssertReturn(uGuestOffset < UINT32_MAX, VERR_INVALID_PARAMETER);
4804
4805 SVGA3dSurfaceImageId image;
4806 image.sid = pSurface->id;
4807 image.face = uHostFace;
4808 image.mipmap = uHostMipmap;
4809
4810 SVGA3dBox box;
4811 box.x = pBox->x;
4812 box.y = pBox->y;
4813 box.z = 0;
4814 box.w = pBox->w;
4815 box.h = pBox->h;
4816 box.d = 1;
4817
4818 VMSVGA3D_SURFACE_MAP const enmMap = transfer == SVGA3D_WRITE_HOST_VRAM
4819 ? VMSVGA3D_SURFACE_MAP_WRITE
4820 : VMSVGA3D_SURFACE_MAP_READ;
4821
4822 VMSVGA3D_MAPPED_SURFACE map;
4823 rc = vmsvga3dBackSurfaceMap(pThisCC, &image, &box, enmMap, &map);
4824 if (RT_SUCCESS(rc))
4825 {
4826 /* Prepare parameters for vmsvgaR3GmrTransfer, which needs the host buffer address, size
4827 * and offset of the first scanline.
4828 */
4829 uint32_t const cbLockedBuf = map.cbRowPitch * cBlocksY;
4830 uint8_t *pu8LockedBuf = (uint8_t *)map.pvData;
4831 uint32_t const offLockedBuf = 0;
4832
4833 rc = vmsvgaR3GmrTransfer(pThis,
4834 pThisCC,
4835 transfer,
4836 pu8LockedBuf,
4837 cbLockedBuf,
4838 offLockedBuf,
4839 map.cbRowPitch,
4840 GuestPtr,
4841 (uint32_t)uGuestOffset,
4842 cbGuestPitch,
4843 cBlocksX * pSurface->cbBlock,
4844 cBlocksY);
4845 AssertRC(rc);
4846
4847 // Log4(("first line:\n%.*Rhxd\n", cBlocksX * pSurface->cbBlock, LockedRect.pBits));
4848
4849 //vmsvga3dMapWriteBmpFile(&map, "Dynamic");
4850
4851 vmsvga3dBackSurfaceUnmap(pThisCC, &image, &map, /* fWritten = */ true);
4852 }
4853#if 0
4854 //DEBUG_BREAKPOINT_TEST();
4855 rc = vmsvga3dBackSurfaceMap(pThisCC, &image, NULL, VMSVGA3D_SURFACE_MAP_READ, &map);
4856 if (RT_SUCCESS(rc))
4857 {
4858 vmsvga3dMapWriteBmpFile(&map, "Staging");
4859
4860 vmsvga3dBackSurfaceUnmap(pThisCC, &image, &map, /* fWritten = */ false);
4861 }
4862#endif
4863 }
4864 else if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
4865 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
4866 {
4867 /** @todo This is generic code and should be in DevVGA-SVGA3d.cpp for backends which support Map/Unmap. */
4868 AssertReturn(uHostFace == 0 && uHostMipmap == 0, VERR_INVALID_PARAMETER);
4869
4870 uint32_t const u32GuestBlockX = pBox->srcx / pSurface->cxBlock;
4871 uint32_t const u32GuestBlockY = pBox->srcy / pSurface->cyBlock;
4872 Assert(u32GuestBlockX * pSurface->cxBlock == pBox->srcx);
4873 Assert(u32GuestBlockY * pSurface->cyBlock == pBox->srcy);
4874 uint32_t const cBlocksX = (pBox->w + pSurface->cxBlock - 1) / pSurface->cxBlock;
4875 uint32_t const cBlocksY = (pBox->h + pSurface->cyBlock - 1) / pSurface->cyBlock;
4876 AssertMsgReturn(cBlocksX && cBlocksY && pBox->d, ("Empty box %dx%dx%d\n", pBox->w, pBox->h, pBox->d), VERR_INTERNAL_ERROR);
4877
4878 /* vmsvgaR3GmrTransfer verifies uGuestOffset.
4879 * srcx(u32GuestBlockX) and srcy(u32GuestBlockY) have been verified in vmsvga3dSurfaceDMA
4880 * to not cause 32 bit overflow when multiplied by cbBlock and cbGuestPitch.
4881 */
4882 uint64_t uGuestOffset = u32GuestBlockX * pSurface->cbBlock + u32GuestBlockY * cbGuestPitch;
4883 AssertReturn(uGuestOffset < UINT32_MAX, VERR_INVALID_PARAMETER);
4884
4885 /* 3D texture needs additional processing. */
4886 ASSERT_GUEST_RETURN( pBox->z < D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
4887 && pBox->d <= D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
4888 && pBox->d <= D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION - pBox->z,
4889 VERR_INVALID_PARAMETER);
4890 ASSERT_GUEST_RETURN( pBox->srcz < D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
4891 && pBox->d <= D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
4892 && pBox->d <= D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION - pBox->srcz,
4893 VERR_INVALID_PARAMETER);
4894
4895 uGuestOffset += pBox->srcz * pMipLevel->cbSurfacePlane;
4896
4897 SVGA3dSurfaceImageId image;
4898 image.sid = pSurface->id;
4899 image.face = uHostFace;
4900 image.mipmap = uHostMipmap;
4901
4902 SVGA3dBox box;
4903 box.x = pBox->x;
4904 box.y = pBox->y;
4905 box.z = pBox->z;
4906 box.w = pBox->w;
4907 box.h = pBox->h;
4908 box.d = pBox->d;
4909
4910 VMSVGA3D_SURFACE_MAP const enmMap = transfer == SVGA3D_WRITE_HOST_VRAM
4911 ? VMSVGA3D_SURFACE_MAP_WRITE
4912 : VMSVGA3D_SURFACE_MAP_READ;
4913
4914 VMSVGA3D_MAPPED_SURFACE map;
4915 rc = vmsvga3dBackSurfaceMap(pThisCC, &image, &box, enmMap, &map);
4916 if (RT_SUCCESS(rc))
4917 {
4918#if 0
4919 if (box.w == 250 && box.h == 250 && box.d == 1 && enmMap == VMSVGA3D_SURFACE_MAP_READ)
4920 {
4921 DEBUG_BREAKPOINT_TEST();
4922 vmsvga3dMapWriteBmpFile(&map, "P");
4923 }
4924#endif
4925 /* Prepare parameters for vmsvgaR3GmrTransfer, which needs the host buffer address, size
4926 * and offset of the first scanline.
4927 */
4928 uint32_t cbLockedBuf = map.cbRowPitch * cBlocksY;
4929 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
4930 cbLockedBuf += map.cbDepthPitch * (pBox->d - 1); /// @todo why map does not compute this for 2D textures
4931 uint8_t *pu8LockedBuf = (uint8_t *)map.pvData;
4932 uint32_t offLockedBuf = 0;
4933
4934 for (uint32_t iPlane = 0; iPlane < pBox->d; ++iPlane)
4935 {
4936 AssertBreak(uGuestOffset < UINT32_MAX);
4937
4938 rc = vmsvgaR3GmrTransfer(pThis,
4939 pThisCC,
4940 transfer,
4941 pu8LockedBuf,
4942 cbLockedBuf,
4943 offLockedBuf,
4944 map.cbRowPitch,
4945 GuestPtr,
4946 (uint32_t)uGuestOffset,
4947 cbGuestPitch,
4948 cBlocksX * pSurface->cbBlock,
4949 cBlocksY);
4950 AssertRC(rc);
4951
4952 uGuestOffset += pMipLevel->cbSurfacePlane;
4953 offLockedBuf += map.cbDepthPitch;
4954 }
4955
4956 bool const fWritten = (transfer == SVGA3D_WRITE_HOST_VRAM);
4957 vmsvga3dBackSurfaceUnmap(pThisCC, &image, &map, fWritten);
4958 }
4959 }
4960 else
4961 {
4962 AssertMsgFailed(("Unsupported surface type %d\n", pBackendSurface->enmResType));
4963 rc = VERR_NOT_IMPLEMENTED;
4964 }
4965
4966 return rc;
4967}
4968
4969
4970/**
4971 * Create D3D/OpenGL texture object for the specified surface.
4972 *
4973 * Surfaces are created when needed.
4974 *
4975 * @param pThisCC The device context.
4976 * @param pContext The context.
4977 * @param idAssociatedContext Probably the same as pContext->id.
4978 * @param pSurface The surface to create the texture for.
4979 */
4980static DECLCALLBACK(int) vmsvga3dBackCreateTexture(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext,
4981 PVMSVGA3DSURFACE pSurface)
4982
4983{
4984 RT_NOREF(pThisCC, pContext, idAssociatedContext, pSurface);
4985
4986 AssertFailed();
4987 return VINF_SUCCESS;
4988}
4989
4990
4991#if 0 /*unused*/
4992static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryCreate(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
4993{
4994 RT_NOREF(pThisCC, pContext);
4995 AssertFailed();
4996 return VINF_SUCCESS;
4997}
4998
4999
5000static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryBegin(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
5001{
5002 RT_NOREF(pThisCC, pContext);
5003 AssertFailed();
5004 return VINF_SUCCESS;
5005}
5006
5007
5008static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryEnd(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
5009{
5010 RT_NOREF(pThisCC, pContext);
5011 AssertFailed();
5012 return VINF_SUCCESS;
5013}
5014
5015
5016static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryGetData(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext, uint32_t *pu32Pixels)
5017{
5018 RT_NOREF(pThisCC, pContext);
5019 *pu32Pixels = 0;
5020 AssertFailed();
5021 return VINF_SUCCESS;
5022}
5023
5024
5025static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryDelete(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
5026{
5027 RT_NOREF(pThisCC, pContext);
5028 AssertFailed();
5029 return VINF_SUCCESS;
5030}
5031#endif
5032
5033
5034/*
5035 * DX callbacks.
5036 */
5037
5038static DECLCALLBACK(int) vmsvga3dBackDXDefineContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5039{
5040 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5041
5042 /* Allocate a backend specific context structure. */
5043 PVMSVGA3DBACKENDDXCONTEXT pBackendDXContext = (PVMSVGA3DBACKENDDXCONTEXT)RTMemAllocZ(sizeof(VMSVGA3DBACKENDDXCONTEXT));
5044 AssertPtrReturn(pBackendDXContext, VERR_NO_MEMORY);
5045 pDXContext->pBackendDXContext = pBackendDXContext;
5046
5047 LogFunc(("cid %d\n", pDXContext->cid));
5048
5049 int rc = dxDeviceCreate(pBackend, &pBackendDXContext->dxDevice);
5050 return rc;
5051}
5052
5053
5054static DECLCALLBACK(int) vmsvga3dBackDXDestroyContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5055{
5056 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5057
5058 LogFunc(("cid %d\n", pDXContext->cid));
5059
5060 if (pDXContext->pBackendDXContext)
5061 {
5062 /* Clean up context resources. */
5063 VMSVGA3DBACKENDDXCONTEXT *pBackendDXContext = pDXContext->pBackendDXContext;
5064
5065 if (pBackendDXContext->paRenderTargetView)
5066 {
5067 for (uint32_t i = 0; i < pBackendDXContext->cRenderTargetView; ++i)
5068 D3D_RELEASE(pBackendDXContext->paRenderTargetView[i].u.pRenderTargetView);
5069 }
5070 if (pBackendDXContext->paDepthStencilView)
5071 {
5072 for (uint32_t i = 0; i < pBackendDXContext->cDepthStencilView; ++i)
5073 D3D_RELEASE(pBackendDXContext->paDepthStencilView[i].u.pDepthStencilView);
5074 }
5075 if (pBackendDXContext->paShaderResourceView)
5076 {
5077 for (uint32_t i = 0; i < pBackendDXContext->cShaderResourceView; ++i)
5078 D3D_RELEASE(pBackendDXContext->paShaderResourceView[i].u.pShaderResourceView);
5079 }
5080 if (pBackendDXContext->paElementLayout)
5081 {
5082 for (uint32_t i = 0; i < pBackendDXContext->cElementLayout; ++i)
5083 D3D_RELEASE(pBackendDXContext->paElementLayout[i].pElementLayout);
5084 }
5085 if (pBackendDXContext->papBlendState)
5086 DX_RELEASE_ARRAY(pBackendDXContext->cBlendState, pBackendDXContext->papBlendState);
5087 if (pBackendDXContext->papDepthStencilState)
5088 DX_RELEASE_ARRAY(pBackendDXContext->cDepthStencilState, pBackendDXContext->papDepthStencilState);
5089 if (pBackendDXContext->papRasterizerState)
5090 DX_RELEASE_ARRAY(pBackendDXContext->cRasterizerState, pBackendDXContext->papRasterizerState);
5091 if (pBackendDXContext->papSamplerState)
5092 DX_RELEASE_ARRAY(pBackendDXContext->cSamplerState, pBackendDXContext->papSamplerState);
5093 if (pBackendDXContext->papQuery)
5094 DX_RELEASE_ARRAY(pBackendDXContext->cQuery, pBackendDXContext->papQuery);
5095 if (pBackendDXContext->paShader)
5096 {
5097 for (uint32_t i = 0; i < pBackendDXContext->cShader; ++i)
5098 dxDestroyShader(&pBackendDXContext->paShader[i]);
5099 }
5100 if (pBackendDXContext->paStreamOutput)
5101 {
5102 for (uint32_t i = 0; i < pBackendDXContext->cStreamOutput; ++i)
5103 dxDestroyStreamOutput(&pBackendDXContext->paStreamOutput[i]);
5104 }
5105
5106 RTMemFreeZ(pBackendDXContext->papBlendState, sizeof(pBackendDXContext->papBlendState[0]) * pBackendDXContext->cBlendState);
5107 RTMemFreeZ(pBackendDXContext->papDepthStencilState, sizeof(pBackendDXContext->papDepthStencilState[0]) * pBackendDXContext->cDepthStencilState);
5108 RTMemFreeZ(pBackendDXContext->papSamplerState, sizeof(pBackendDXContext->papSamplerState[0]) * pBackendDXContext->cSamplerState);
5109 RTMemFreeZ(pBackendDXContext->papRasterizerState, sizeof(pBackendDXContext->papRasterizerState[0]) * pBackendDXContext->cRasterizerState);
5110 RTMemFreeZ(pBackendDXContext->paElementLayout, sizeof(pBackendDXContext->paElementLayout[0]) * pBackendDXContext->cElementLayout);
5111 RTMemFreeZ(pBackendDXContext->paRenderTargetView, sizeof(pBackendDXContext->paRenderTargetView[0]) * pBackendDXContext->cRenderTargetView);
5112 RTMemFreeZ(pBackendDXContext->paDepthStencilView, sizeof(pBackendDXContext->paDepthStencilView[0]) * pBackendDXContext->cDepthStencilView);
5113 RTMemFreeZ(pBackendDXContext->paShaderResourceView, sizeof(pBackendDXContext->paShaderResourceView[0]) * pBackendDXContext->cShaderResourceView);
5114 RTMemFreeZ(pBackendDXContext->papQuery, sizeof(pBackendDXContext->papQuery[0]) * pBackendDXContext->cQuery);
5115 RTMemFreeZ(pBackendDXContext->paShader, sizeof(pBackendDXContext->paShader[0]) * pBackendDXContext->cShader);
5116 RTMemFreeZ(pBackendDXContext->paStreamOutput, sizeof(pBackendDXContext->paStreamOutput[0]) * pBackendDXContext->cStreamOutput);
5117
5118 /* Destroy backend surfaces which belong to this context. */
5119 /** @todo The context should have a list of surfaces (and also shared resources). */
5120 for (uint32_t sid = 0; sid < pThisCC->svga.p3dState->cSurfaces; ++sid)
5121 {
5122 PVMSVGA3DSURFACE const pSurface = pThisCC->svga.p3dState->papSurfaces[sid];
5123 if ( pSurface
5124 && pSurface->id == sid)
5125 {
5126 if (pSurface->idAssociatedContext == pDXContext->cid)
5127 {
5128 if (pSurface->pBackendSurface)
5129 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
5130 }
5131 else if (pSurface->idAssociatedContext == DX_CID_BACKEND)
5132 {
5133 /* May have shared resources in this context. */
5134 if (pSurface->pBackendSurface)
5135 {
5136 DXSHAREDTEXTURE *pSharedTexture = (DXSHAREDTEXTURE *)RTAvlU32Get(&pSurface->pBackendSurface->SharedTextureTree, pDXContext->cid);
5137 if (pSharedTexture)
5138 {
5139 Assert(pSharedTexture->sid == sid);
5140 RTAvlU32Remove(&pSurface->pBackendSurface->SharedTextureTree, pDXContext->cid);
5141 D3D_RELEASE(pSharedTexture->pTexture);
5142 RTMemFreeZ(pSharedTexture, sizeof(*pSharedTexture));
5143 }
5144 }
5145 }
5146 }
5147 }
5148
5149 dxDeviceDestroy(pBackend, &pBackendDXContext->dxDevice);
5150
5151 RTMemFreeZ(pBackendDXContext, sizeof(*pBackendDXContext));
5152 pDXContext->pBackendDXContext = NULL;
5153 }
5154 return VINF_SUCCESS;
5155}
5156
5157
5158static DECLCALLBACK(int) vmsvga3dBackDXBindContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5159{
5160 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5161 RT_NOREF(pBackend, pDXContext);
5162 return VINF_SUCCESS;
5163}
5164
5165
5166static DECLCALLBACK(int) vmsvga3dBackDXSwitchContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5167{
5168 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5169 if (!pBackend->fSingleDevice)
5170 return VINF_NOT_IMPLEMENTED; /* Not required. */
5171
5172 /* The new context state will be applied by the generic DX code. */
5173 RT_NOREF(pDXContext);
5174 return VINF_SUCCESS;
5175}
5176
5177
5178static DECLCALLBACK(int) vmsvga3dBackDXReadbackContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5179{
5180 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5181 RT_NOREF(pBackend, pDXContext);
5182 return VINF_SUCCESS;
5183}
5184
5185
5186static DECLCALLBACK(int) vmsvga3dBackDXInvalidateContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5187{
5188 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5189
5190 RT_NOREF(pBackend, pDXContext);
5191 AssertFailed(); /** @todo Implement */
5192 return VERR_NOT_IMPLEMENTED;
5193}
5194
5195
5196static DECLCALLBACK(int) vmsvga3dBackDXSetSingleConstantBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t slot, SVGA3dShaderType type, SVGA3dSurfaceId sid, uint32_t offsetInBytes, uint32_t sizeInBytes)
5197{
5198 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5199 RT_NOREF(pBackend);
5200
5201 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5202 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5203
5204 if (sid == SVGA_ID_INVALID)
5205 {
5206 dxConstantBufferSet(pDevice, slot, type, NULL);
5207 return VINF_SUCCESS;
5208 }
5209
5210 PVMSVGA3DSURFACE pSurface;
5211 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
5212 AssertRCReturn(rc, rc);
5213
5214 PVMSVGA3DMIPMAPLEVEL pMipLevel;
5215 rc = vmsvga3dMipmapLevel(pSurface, 0, 0, &pMipLevel);
5216 AssertRCReturn(rc, rc);
5217
5218 uint32_t const cbSurface = pMipLevel->cbSurface;
5219 ASSERT_GUEST_RETURN( offsetInBytes < cbSurface
5220 && sizeInBytes <= cbSurface - offsetInBytes, VERR_INVALID_PARAMETER);
5221
5222 /* Constant buffers are created on demand. */
5223 Assert(pSurface->pBackendSurface == NULL);
5224
5225 /* Upload the current data, if any. */
5226 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
5227 D3D11_SUBRESOURCE_DATA initialData;
5228 if (pMipLevel->pSurfaceData)
5229 {
5230 initialData.pSysMem = (uint8_t *)pMipLevel->pSurfaceData + offsetInBytes;
5231 initialData.SysMemPitch = sizeInBytes;
5232 initialData.SysMemSlicePitch = sizeInBytes;
5233
5234 pInitialData = &initialData;
5235 }
5236
5237 D3D11_BUFFER_DESC bd;
5238 RT_ZERO(bd);
5239 bd.ByteWidth = sizeInBytes;
5240 bd.Usage = D3D11_USAGE_DEFAULT;
5241 bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
5242 bd.CPUAccessFlags = 0;
5243 bd.MiscFlags = 0;
5244 bd.StructureByteStride = 0;
5245
5246 ID3D11Buffer *pBuffer = 0;
5247 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBuffer);
5248 if (SUCCEEDED(hr))
5249 {
5250 dxConstantBufferSet(pDevice, slot, type, pBuffer);
5251 D3D_RELEASE(pBuffer);
5252 }
5253
5254 return VINF_SUCCESS;
5255}
5256
5257static int dxSetShaderResources(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderType type)
5258{
5259 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5260 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5261
5262//DEBUG_BREAKPOINT_TEST();
5263 AssertReturn(type >= SVGA3D_SHADERTYPE_MIN && type < SVGA3D_SHADERTYPE_MAX, VERR_INVALID_PARAMETER);
5264 uint32_t const idxShaderState = type - SVGA3D_SHADERTYPE_MIN;
5265 uint32_t const *pSRIds = &pDXContext->svgaDXContext.shaderState[idxShaderState].shaderResources[0];
5266 ID3D11ShaderResourceView *papShaderResourceView[SVGA3D_DX_MAX_SRVIEWS];
5267 for (uint32_t i = 0; i < SVGA3D_DX_MAX_SRVIEWS; ++i)
5268 {
5269 SVGA3dShaderResourceViewId shaderResourceViewId = pSRIds[i];
5270 if (shaderResourceViewId != SVGA3D_INVALID_ID)
5271 {
5272 ASSERT_GUEST_RETURN(shaderResourceViewId < pDXContext->pBackendDXContext->cShaderResourceView, VERR_INVALID_PARAMETER);
5273
5274 DXVIEW *pDXView = &pDXContext->pBackendDXContext->paShaderResourceView[shaderResourceViewId];
5275 Assert(pDXView->u.pShaderResourceView);
5276 papShaderResourceView[i] = pDXView->u.pShaderResourceView;
5277 }
5278 else
5279 papShaderResourceView[i] = NULL;
5280 }
5281
5282 dxShaderResourceViewSet(pDevice, type, 0, SVGA3D_DX_MAX_SRVIEWS, papShaderResourceView);
5283 return VINF_SUCCESS;
5284}
5285
5286
5287static DECLCALLBACK(int) vmsvga3dBackDXSetShaderResources(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t startView, SVGA3dShaderType type, uint32_t cShaderResourceViewId, SVGA3dShaderResourceViewId const *paShaderResourceViewId)
5288{
5289 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5290 RT_NOREF(pBackend);
5291
5292 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5293 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5294
5295 RT_NOREF(startView, type, cShaderResourceViewId, paShaderResourceViewId);
5296
5297 return VINF_SUCCESS;
5298}
5299
5300
5301static DECLCALLBACK(int) vmsvga3dBackDXSetShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, SVGA3dShaderType type)
5302{
5303 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5304 RT_NOREF(pBackend);
5305
5306 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5307 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5308
5309 RT_NOREF(shaderId, type);
5310
5311 return VINF_SUCCESS;
5312}
5313
5314
5315static DECLCALLBACK(int) vmsvga3dBackDXSetSamplers(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t startSampler, SVGA3dShaderType type, uint32_t cSamplerId, SVGA3dSamplerId const *paSamplerId)
5316{
5317 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5318 RT_NOREF(pBackend);
5319
5320 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5321 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5322
5323 ID3D11SamplerState *papSamplerState[SVGA3D_DX_MAX_SAMPLERS];
5324 for (uint32_t i = 0; i < cSamplerId; ++i)
5325 {
5326 SVGA3dSamplerId samplerId = paSamplerId[i];
5327 if (samplerId != SVGA3D_INVALID_ID)
5328 {
5329 ASSERT_GUEST_RETURN(samplerId < pDXContext->pBackendDXContext->cSamplerState, VERR_INVALID_PARAMETER);
5330 papSamplerState[i] = pDXContext->pBackendDXContext->papSamplerState[samplerId];
5331 }
5332 else
5333 papSamplerState[i] = NULL;
5334 }
5335
5336 dxSamplerSet(pDevice, type, startSampler, cSamplerId, papSamplerState);
5337 return VINF_SUCCESS;
5338}
5339
5340
5341static void dxSetupPipeline(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5342{
5343 /* Make sure that any draw operations on shader resource views have finished. */
5344 AssertCompile(RT_ELEMENTS(pDXContext->svgaDXContext.shaderState) == SVGA3D_NUM_SHADERTYPE);
5345 AssertCompile(RT_ELEMENTS(pDXContext->svgaDXContext.shaderState[0].shaderResources) == SVGA3D_DX_MAX_SRVIEWS);
5346
5347 int rc;
5348
5349 /* Unbind render target views because they mught be (re-)used as shader resource views. */
5350 DXDEVICE *pDXDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5351 pDXDevice->pImmediateContext->OMSetRenderTargets(0, NULL, NULL);
5352
5353 /*
5354 * Shader resources
5355 */
5356
5357 /* Make sure that the shader resource views exist. */
5358 for (uint32_t idxShaderState = 0; idxShaderState < SVGA3D_NUM_SHADERTYPE_DX10 /** @todo SVGA3D_NUM_SHADERTYPE*/; ++idxShaderState)
5359 {
5360 for (uint32_t idxSR = 0; idxSR < SVGA3D_DX_MAX_SRVIEWS; ++idxSR)
5361 {
5362 SVGA3dShaderResourceViewId const shaderResourceViewId = pDXContext->svgaDXContext.shaderState[idxShaderState].shaderResources[idxSR];
5363 if (shaderResourceViewId != SVGA3D_INVALID_ID)
5364 {
5365 ASSERT_GUEST_RETURN_VOID(shaderResourceViewId < pDXContext->pBackendDXContext->cShaderResourceView);
5366
5367 SVGACOTableDXSRViewEntry const *pSRViewEntry = dxGetShaderResourceViewEntry(pDXContext, shaderResourceViewId);
5368 AssertContinue(pSRViewEntry != NULL);
5369
5370 uint32_t const sid = pSRViewEntry->sid;
5371
5372 PVMSVGA3DSURFACE pSurface;
5373 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
5374 AssertRCReturnVoid(rc);
5375
5376 /* The guest might have invalidated the surface in which case pSurface->pBackendSurface is NULL. */
5377 /** @todo This is not needed for "single DX device" mode. */
5378 if (pSurface->pBackendSurface)
5379 {
5380 /* Wait for the surface to finish drawing. */
5381 dxSurfaceWait(pThisCC->svga.p3dState, pSurface, pDXContext->cid);
5382 }
5383
5384 /* If a view has not been created yet, do it now. */
5385 if (!pDXContext->pBackendDXContext->paShaderResourceView[shaderResourceViewId].u.pView)
5386 {
5387//DEBUG_BREAKPOINT_TEST();
5388 LogFunc(("Re-creating SRV: sid=%u srvid = %u\n", sid, shaderResourceViewId));
5389 rc = dxDefineShaderResourceView(pThisCC, pDXContext, shaderResourceViewId, pSRViewEntry);
5390 AssertContinue(RT_SUCCESS(rc));
5391 }
5392
5393 LogFunc(("srv[%d][%d] sid = %u, srvid = %u\n", idxShaderState, idxSR, sid, shaderResourceViewId));
5394
5395#ifdef DUMP_BITMAPS
5396 SVGA3dSurfaceImageId image;
5397 image.sid = sid;
5398 image.face = 0;
5399 image.mipmap = 0;
5400 VMSVGA3D_MAPPED_SURFACE map;
5401 int rc2 = vmsvga3dSurfaceMap(pThisCC, &image, NULL, VMSVGA3D_SURFACE_MAP_READ, &map);
5402 if (RT_SUCCESS(rc2))
5403 {
5404 vmsvga3dMapWriteBmpFile(&map, "sr-");
5405 vmsvga3dSurfaceUnmap(pThisCC, &image, &map, /* fWritten = */ false);
5406 }
5407 else
5408 Log(("Map failed %Rrc\n", rc));
5409#endif
5410 }
5411 }
5412
5413 /* Set shader resources. */
5414 rc = dxSetShaderResources(pThisCC, pDXContext, (SVGA3dShaderType)(idxShaderState + SVGA3D_SHADERTYPE_MIN));
5415 AssertRC(rc);
5416 }
5417
5418 /*
5419 * Render targets
5420 */
5421
5422 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5423 AssertReturnVoid(pDevice->pDevice);
5424
5425 /* Make sure that the render target views exist. Similar to SRVs. */
5426 if (pDXContext->svgaDXContext.renderState.depthStencilViewId != SVGA3D_INVALID_ID)
5427 {
5428 uint32_t const viewId = pDXContext->svgaDXContext.renderState.depthStencilViewId;
5429
5430 ASSERT_GUEST_RETURN_VOID(viewId < pDXContext->pBackendDXContext->cDepthStencilView);
5431
5432 SVGACOTableDXDSViewEntry const *pDSViewEntry = dxGetDepthStencilViewEntry(pDXContext, viewId);
5433 AssertReturnVoid(pDSViewEntry != NULL);
5434
5435 PVMSVGA3DSURFACE pSurface;
5436 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pDSViewEntry->sid, &pSurface);
5437 AssertRCReturnVoid(rc);
5438
5439 /* If a view has not been created yet, do it now. */
5440 if (!pDXContext->pBackendDXContext->paDepthStencilView[viewId].u.pView)
5441 {
5442//DEBUG_BREAKPOINT_TEST();
5443 LogFunc(("Re-creating DSV: sid=%u dsvid = %u\n", pDSViewEntry->sid, viewId));
5444 rc = dxDefineDepthStencilView(pThisCC, pDXContext, viewId, pDSViewEntry);
5445 AssertReturnVoid(RT_SUCCESS(rc));
5446 }
5447 }
5448
5449 for (uint32_t i = 0; i < SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS; ++i)
5450 {
5451 if (pDXContext->svgaDXContext.renderState.renderTargetViewIds[i] != SVGA3D_INVALID_ID)
5452 {
5453 uint32_t const viewId = pDXContext->svgaDXContext.renderState.renderTargetViewIds[i];
5454
5455 ASSERT_GUEST_RETURN_VOID(viewId < pDXContext->pBackendDXContext->cRenderTargetView);
5456
5457 SVGACOTableDXRTViewEntry const *pRTViewEntry = dxGetRenderTargetViewEntry(pDXContext, viewId);
5458 AssertReturnVoid(pRTViewEntry != NULL);
5459
5460 PVMSVGA3DSURFACE pSurface;
5461 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pRTViewEntry->sid, &pSurface);
5462 AssertRCReturnVoid(rc);
5463
5464 /* If a view has not been created yet, do it now. */
5465 if (!pDXContext->pBackendDXContext->paRenderTargetView[viewId].u.pView)
5466 {
5467//DEBUG_BREAKPOINT_TEST();
5468 LogFunc(("Re-creating RTV: sid=%u rtvid = %u\n", pRTViewEntry->sid, viewId));
5469 rc = dxDefineRenderTargetView(pThisCC, pDXContext, viewId, pRTViewEntry);
5470 AssertReturnVoid(RT_SUCCESS(rc));
5471 }
5472 }
5473 }
5474
5475 /* Set render targets. */
5476 rc = dxSetRenderTargets(pThisCC, pDXContext);
5477 AssertRC(rc);
5478
5479 /*
5480 * Shaders
5481 */
5482
5483 for (uint32_t idxShaderState = 0; idxShaderState < SVGA3D_NUM_SHADERTYPE_DX10 /** @todo SVGA3D_NUM_SHADERTYPE*/; ++idxShaderState)
5484 {
5485 DXSHADER *pDXShader;
5486 SVGA3dShaderType const shaderType = (SVGA3dShaderType)(idxShaderState + SVGA3D_SHADERTYPE_MIN);
5487 SVGA3dShaderId const shaderId = pDXContext->svgaDXContext.shaderState[idxShaderState].shaderId;
5488
5489 if (shaderId != SVGA3D_INVALID_ID)
5490 {
5491 pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
5492 if (pDXShader->pShader == NULL)
5493 {
5494 /* Create a new shader. */
5495 Log(("Shader: cid=%u shid=%u type=%d\n", pDXContext->cid, shaderId, pDXShader->enmShaderType));
5496
5497 /* Apply resource types to a pixel shader. */
5498 if (shaderType == SVGA3D_SHADERTYPE_PS)
5499 {
5500 SVGA3dResourceType aResourceType[SVGA3D_DX_MAX_SRVIEWS];
5501 RT_ZERO(aResourceType);
5502 uint32_t cResourceType = 0;
5503
5504 for (uint32_t idxSR = 0; idxSR < SVGA3D_DX_MAX_SRVIEWS; ++idxSR)
5505 {
5506 SVGA3dShaderResourceViewId const shaderResourceViewId = pDXContext->svgaDXContext.shaderState[idxShaderState].shaderResources[idxSR];
5507 if (shaderResourceViewId != SVGA3D_INVALID_ID)
5508 {
5509 SVGACOTableDXSRViewEntry const *pSRViewEntry = dxGetShaderResourceViewEntry(pDXContext, shaderResourceViewId);
5510 AssertContinue(pSRViewEntry != NULL);
5511
5512 aResourceType[idxSR] = pSRViewEntry->resourceDimension;
5513 cResourceType = idxSR + 1;
5514 }
5515 }
5516
5517 rc = DXShaderUpdateResourceTypes(&pDXShader->shaderInfo, aResourceType, cResourceType);
5518 AssertRC(rc); /* Ignore rc because the shader will most likely work anyway. */
5519 }
5520
5521 rc = DXShaderCreateDXBC(&pDXShader->shaderInfo, &pDXShader->pvDXBC, &pDXShader->cbDXBC);
5522 if (RT_SUCCESS(rc))
5523 {
5524#ifdef LOG_ENABLED
5525 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5526 if (pBackend->pfnD3DDisassemble && LogIs6Enabled())
5527 {
5528 ID3D10Blob *pBlob = 0;
5529 HRESULT hr2 = pBackend->pfnD3DDisassemble(pDXShader->pvDXBC, pDXShader->cbDXBC, 0, NULL, &pBlob);
5530 if (SUCCEEDED(hr2) && pBlob && pBlob->GetBufferSize())
5531 Log6(("%s\n", pBlob->GetBufferPointer()));
5532 else
5533 AssertFailed();
5534 D3D_RELEASE(pBlob);
5535 }
5536#endif
5537
5538 HRESULT hr = dxShaderCreate(pThisCC, pDXContext, pDXShader);
5539 if (FAILED(hr))
5540 rc = VERR_INVALID_STATE;
5541 }
5542 else
5543 rc = VERR_NO_MEMORY;
5544 }
5545 }
5546 else
5547 pDXShader = NULL;
5548
5549 if (RT_SUCCESS(rc))
5550 dxShaderSet(pThisCC, pDXContext, shaderType, pDXShader);
5551
5552 AssertRC(rc);
5553 }
5554
5555 /*
5556 * InputLayout
5557 */
5558 SVGA3dElementLayoutId const elementLayoutId = pDXContext->svgaDXContext.inputAssembly.layoutId;
5559 ID3D11InputLayout *pInputLayout = NULL;
5560 if (elementLayoutId != SVGA3D_INVALID_ID)
5561 {
5562 DXELEMENTLAYOUT *pDXElementLayout = &pDXContext->pBackendDXContext->paElementLayout[elementLayoutId];
5563 if (!pDXElementLayout->pElementLayout)
5564 {
5565 uint32_t const idxShaderState = SVGA3D_SHADERTYPE_VS - SVGA3D_SHADERTYPE_MIN;
5566 uint32_t const shid = pDXContext->svgaDXContext.shaderState[idxShaderState].shaderId;
5567 if (shid < pDXContext->pBackendDXContext->cShader)
5568 {
5569 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shid];
5570 if (pDXShader->pvDXBC)
5571 {
5572 HRESULT hr = pDevice->pDevice->CreateInputLayout(pDXElementLayout->aElementDesc,
5573 pDXElementLayout->cElementDesc,
5574 pDXShader->pvDXBC,
5575 pDXShader->cbDXBC,
5576 &pDXElementLayout->pElementLayout);
5577 Assert(SUCCEEDED(hr)); RT_NOREF(hr);
5578 }
5579 else
5580 LogRelMax(16, ("VMSVGA: DX shader bytecode is not available in DXSetInputLayout: shid = %u\n", shid));
5581 }
5582 else
5583 LogRelMax(16, ("VMSVGA: DX shader is not set in DXSetInputLayout: shid = 0x%x\n", shid));
5584 }
5585
5586 pInputLayout = pDXElementLayout->pElementLayout;
5587 }
5588
5589 pDevice->pImmediateContext->IASetInputLayout(pInputLayout);
5590}
5591
5592
5593static DECLCALLBACK(int) vmsvga3dBackDXDraw(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t vertexCount, uint32_t startVertexLocation)
5594{
5595 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5596 RT_NOREF(pBackend);
5597
5598 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5599 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5600
5601 dxSetupPipeline(pThisCC, pDXContext);
5602
5603 if (pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN)
5604 pDevice->pImmediateContext->Draw(vertexCount, startVertexLocation);
5605 else
5606 {
5607 /*
5608 * Emulate SVGA3D_PRIMITIVE_TRIANGLEFAN using an indexed draw of a triangle list.
5609 */
5610
5611 /* Make sure that 16 bit indices are enough. 20000 ~= 65536 / 3 */
5612 AssertReturn(vertexCount <= 20000, VERR_NOT_SUPPORTED);
5613
5614 /* Generate indices. */
5615 UINT const IndexCount = 3 * (vertexCount - 2); /* 3_per_triangle * num_triangles */
5616 UINT const cbAlloc = IndexCount * sizeof(USHORT);
5617 USHORT *paIndices = (USHORT *)RTMemAlloc(cbAlloc);
5618 AssertReturn(paIndices, VERR_NO_MEMORY);
5619 USHORT iVertex = 1;
5620 for (UINT i = 0; i < IndexCount; i+= 3)
5621 {
5622 paIndices[i] = 0;
5623 paIndices[i + 1] = iVertex;
5624 ++iVertex;
5625 paIndices[i + 2] = iVertex;
5626 }
5627
5628 D3D11_SUBRESOURCE_DATA InitData;
5629 InitData.pSysMem = paIndices;
5630 InitData.SysMemPitch = cbAlloc;
5631 InitData.SysMemSlicePitch = cbAlloc;
5632
5633 D3D11_BUFFER_DESC bd;
5634 RT_ZERO(bd);
5635 bd.ByteWidth = cbAlloc;
5636 bd.Usage = D3D11_USAGE_IMMUTABLE;
5637 bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
5638 //bd.CPUAccessFlags = 0;
5639 //bd.MiscFlags = 0;
5640 //bd.StructureByteStride = 0;
5641
5642 ID3D11Buffer *pIndexBuffer = 0;
5643 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, &InitData, &pIndexBuffer);
5644 Assert(SUCCEEDED(hr));RT_NOREF(hr);
5645
5646 /* Save the current index buffer. */
5647 ID3D11Buffer *pSavedIndexBuffer = 0;
5648 DXGI_FORMAT SavedFormat = DXGI_FORMAT_UNKNOWN;
5649 UINT SavedOffset = 0;
5650 pDevice->pImmediateContext->IAGetIndexBuffer(&pSavedIndexBuffer, &SavedFormat, &SavedOffset);
5651
5652 /* Set up the device state. */
5653 pDevice->pImmediateContext->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
5654 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5655
5656 UINT const StartIndexLocation = 0;
5657 INT const BaseVertexLocation = startVertexLocation;
5658 pDevice->pImmediateContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation);
5659
5660 /* Restore the device state. */
5661 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
5662 pDevice->pImmediateContext->IASetIndexBuffer(pSavedIndexBuffer, SavedFormat, SavedOffset);
5663 D3D_RELEASE(pSavedIndexBuffer);
5664
5665 /* Cleanup. */
5666 D3D_RELEASE(pIndexBuffer);
5667 RTMemFree(paIndices);
5668 }
5669
5670 /* Note which surfaces are being drawn. */
5671 dxTrackRenderTargets(pThisCC, pDXContext);
5672
5673 return VINF_SUCCESS;
5674}
5675
5676static int dxReadBuffer(DXDEVICE *pDevice, ID3D11Buffer *pBuffer, UINT Offset, UINT Bytes, void **ppvData, uint32_t *pcbData)
5677{
5678 D3D11_BUFFER_DESC desc;
5679 RT_ZERO(desc);
5680 pBuffer->GetDesc(&desc);
5681
5682 AssertReturn( Offset < desc.ByteWidth
5683 && Bytes <= desc.ByteWidth - Offset, VERR_INVALID_STATE);
5684
5685 void *pvData = RTMemAlloc(Bytes);
5686 if (!pvData)
5687 return VERR_NO_MEMORY;
5688
5689 *ppvData = pvData;
5690 *pcbData = Bytes;
5691
5692 int rc = dxStagingBufferRealloc(pDevice, Bytes);
5693 if (RT_SUCCESS(rc))
5694 {
5695 /* Copy from the buffer to the staging buffer. */
5696 ID3D11Resource *pDstResource = pDevice->pStagingBuffer;
5697 UINT DstSubresource = 0;
5698 UINT DstX = Offset;
5699 UINT DstY = 0;
5700 UINT DstZ = 0;
5701 ID3D11Resource *pSrcResource = pBuffer;
5702 UINT SrcSubresource = 0;
5703 D3D11_BOX SrcBox;
5704 SrcBox.left = 0;
5705 SrcBox.top = 0;
5706 SrcBox.front = 0;
5707 SrcBox.right = Bytes;
5708 SrcBox.bottom = 1;
5709 SrcBox.back = 1;
5710 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
5711 pSrcResource, SrcSubresource, &SrcBox);
5712
5713 D3D11_MAPPED_SUBRESOURCE mappedResource;
5714 UINT const Subresource = 0; /* Buffers have only one subresource. */
5715 HRESULT hr = pDevice->pImmediateContext->Map(pDevice->pStagingBuffer, Subresource,
5716 D3D11_MAP_READ, /* MapFlags = */ 0, &mappedResource);
5717 if (SUCCEEDED(hr))
5718 {
5719 memcpy(pvData, mappedResource.pData, Bytes);
5720
5721 /* Unmap the staging buffer. */
5722 pDevice->pImmediateContext->Unmap(pDevice->pStagingBuffer, Subresource);
5723 }
5724 else
5725 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
5726
5727 }
5728
5729 if (RT_FAILURE(rc))
5730 {
5731 RTMemFree(*ppvData);
5732 *ppvData = NULL;
5733 *pcbData = 0;
5734 }
5735
5736 return rc;
5737}
5738
5739
5740static int dxDrawIndexedTriangleFan(DXDEVICE *pDevice, uint32_t IndexCountTF, uint32_t StartIndexLocationTF, int32_t BaseVertexLocationTF)
5741{
5742 /*
5743 * Emulate an indexed SVGA3D_PRIMITIVE_TRIANGLEFAN using an indexed draw of triangle list.
5744 */
5745
5746 /* Make sure that 16 bit indices are enough. 20000 ~= 65536 / 3 */
5747 AssertReturn(IndexCountTF <= 20000, VERR_NOT_SUPPORTED);
5748
5749 /* Save the current index buffer. */
5750 ID3D11Buffer *pSavedIndexBuffer = 0;
5751 DXGI_FORMAT SavedFormat = DXGI_FORMAT_UNKNOWN;
5752 UINT SavedOffset = 0;
5753 pDevice->pImmediateContext->IAGetIndexBuffer(&pSavedIndexBuffer, &SavedFormat, &SavedOffset);
5754
5755 AssertReturn( SavedFormat == DXGI_FORMAT_R16_UINT
5756 || SavedFormat == DXGI_FORMAT_R32_UINT, VERR_NOT_SUPPORTED);
5757
5758 /* How many bytes are used by triangle fan indices. */
5759 UINT const BytesPerIndexTF = SavedFormat == DXGI_FORMAT_R16_UINT ? 2 : 4;
5760 UINT const BytesTF = BytesPerIndexTF * IndexCountTF;
5761
5762 /* Read the current index buffer content to obtain indices. */
5763 void *pvDataTF;
5764 uint32_t cbDataTF;
5765 int rc = dxReadBuffer(pDevice, pSavedIndexBuffer, StartIndexLocationTF, BytesTF, &pvDataTF, &cbDataTF);
5766 AssertRCReturn(rc, rc);
5767 AssertReturnStmt(cbDataTF >= BytesPerIndexTF, RTMemFree(pvDataTF), VERR_INVALID_STATE);
5768
5769 /* Generate indices for triangle list. */
5770 UINT const IndexCount = 3 * (IndexCountTF - 2); /* 3_per_triangle * num_triangles */
5771 UINT const cbAlloc = IndexCount * sizeof(USHORT);
5772 USHORT *paIndices = (USHORT *)RTMemAlloc(cbAlloc);
5773 AssertReturnStmt(paIndices, RTMemFree(pvDataTF), VERR_NO_MEMORY);
5774
5775 USHORT iVertex = 1;
5776 if (BytesPerIndexTF == 2)
5777 {
5778 USHORT *paIndicesTF = (USHORT *)pvDataTF;
5779 for (UINT i = 0; i < IndexCount; i+= 3)
5780 {
5781 paIndices[i] = paIndicesTF[0];
5782 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5783 paIndices[i + 1] = paIndicesTF[iVertex];
5784 ++iVertex;
5785 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5786 paIndices[i + 2] = paIndicesTF[iVertex];
5787 }
5788 }
5789 else
5790 {
5791 UINT *paIndicesTF = (UINT *)pvDataTF;
5792 for (UINT i = 0; i < IndexCount; i+= 3)
5793 {
5794 paIndices[i] = paIndicesTF[0];
5795 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5796 paIndices[i + 1] = paIndicesTF[iVertex];
5797 ++iVertex;
5798 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5799 paIndices[i + 2] = paIndicesTF[iVertex];
5800 }
5801 }
5802
5803 D3D11_SUBRESOURCE_DATA InitData;
5804 InitData.pSysMem = paIndices;
5805 InitData.SysMemPitch = cbAlloc;
5806 InitData.SysMemSlicePitch = cbAlloc;
5807
5808 D3D11_BUFFER_DESC bd;
5809 RT_ZERO(bd);
5810 bd.ByteWidth = cbAlloc;
5811 bd.Usage = D3D11_USAGE_IMMUTABLE;
5812 bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
5813 //bd.CPUAccessFlags = 0;
5814 //bd.MiscFlags = 0;
5815 //bd.StructureByteStride = 0;
5816
5817 ID3D11Buffer *pIndexBuffer = 0;
5818 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, &InitData, &pIndexBuffer);
5819 Assert(SUCCEEDED(hr));RT_NOREF(hr);
5820
5821 /* Set up the device state. */
5822 pDevice->pImmediateContext->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
5823 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5824
5825 UINT const StartIndexLocation = 0;
5826 INT const BaseVertexLocation = BaseVertexLocationTF;
5827 pDevice->pImmediateContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation);
5828
5829 /* Restore the device state. */
5830 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
5831 pDevice->pImmediateContext->IASetIndexBuffer(pSavedIndexBuffer, SavedFormat, SavedOffset);
5832 D3D_RELEASE(pSavedIndexBuffer);
5833
5834 /* Cleanup. */
5835 D3D_RELEASE(pIndexBuffer);
5836 RTMemFree(paIndices);
5837 RTMemFree(pvDataTF);
5838
5839 return VINF_SUCCESS;
5840}
5841
5842
5843static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexed(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t indexCount, uint32_t startIndexLocation, int32_t baseVertexLocation)
5844{
5845 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5846 RT_NOREF(pBackend);
5847
5848 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5849 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5850
5851 dxSetupPipeline(pThisCC, pDXContext);
5852
5853 if (pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN)
5854 pDevice->pImmediateContext->DrawIndexed(indexCount, startIndexLocation, baseVertexLocation);
5855 else
5856 {
5857 dxDrawIndexedTriangleFan(pDevice, indexCount, startIndexLocation, baseVertexLocation);
5858 }
5859
5860 /* Note which surfaces are being drawn. */
5861 dxTrackRenderTargets(pThisCC, pDXContext);
5862
5863 return VINF_SUCCESS;
5864}
5865
5866
5867static DECLCALLBACK(int) vmsvga3dBackDXDrawInstanced(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
5868 uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation)
5869{
5870 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5871 RT_NOREF(pBackend);
5872
5873 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5874 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5875
5876 dxSetupPipeline(pThisCC, pDXContext);
5877
5878 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
5879
5880 pDevice->pImmediateContext->DrawInstanced(vertexCountPerInstance, instanceCount, startVertexLocation, startInstanceLocation);
5881
5882 /* Note which surfaces are being drawn. */
5883 dxTrackRenderTargets(pThisCC, pDXContext);
5884
5885 return VINF_SUCCESS;
5886}
5887
5888
5889static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexedInstanced(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
5890 uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation)
5891{
5892 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5893 RT_NOREF(pBackend);
5894
5895 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5896 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5897
5898 dxSetupPipeline(pThisCC, pDXContext);
5899
5900 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
5901
5902 pDevice->pImmediateContext->DrawIndexedInstanced(indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation);
5903
5904 /* Note which surfaces are being drawn. */
5905 dxTrackRenderTargets(pThisCC, pDXContext);
5906
5907 return VINF_SUCCESS;
5908}
5909
5910
5911static DECLCALLBACK(int) vmsvga3dBackDXDrawAuto(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5912{
5913 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
5914 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5915
5916 dxSetupPipeline(pThisCC, pDXContext);
5917
5918 RT_NOREF(pBackend, pDXContext);
5919 AssertFailed(); /** @todo Implement */
5920 return VERR_NOT_IMPLEMENTED;
5921}
5922
5923
5924static DECLCALLBACK(int) vmsvga3dBackDXSetInputLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId)
5925{
5926 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5927 RT_NOREF(pBackend);
5928
5929 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5930 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5931
5932 RT_NOREF(elementLayoutId);
5933
5934 return VINF_SUCCESS;
5935}
5936
5937
5938static DECLCALLBACK(int) vmsvga3dBackDXSetVertexBuffers(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t startBuffer, uint32_t cVertexBuffer, SVGA3dVertexBuffer const *paVertexBuffer)
5939{
5940 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5941 RT_NOREF(pBackend);
5942
5943 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5944 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5945
5946 /* For each paVertexBuffer[i]:
5947 * If the vertex buffer object does not exist then create it.
5948 * If the surface has been updated by the guest then update the buffer object.
5949 * Use IASetVertexBuffers to set the buffers.
5950 */
5951
5952 ID3D11Buffer *paResources[SVGA3D_DX_MAX_VERTEXBUFFERS];
5953 UINT paStride[SVGA3D_DX_MAX_VERTEXBUFFERS];
5954 UINT paOffset[SVGA3D_DX_MAX_VERTEXBUFFERS];
5955
5956 for (uint32_t i = 0; i < cVertexBuffer; ++i)
5957 {
5958 uint32_t const idxVertexBuffer = startBuffer + i;
5959
5960 /* Get corresponding resource. Create the buffer if does not yet exist. */
5961 if (paVertexBuffer[i].sid != SVGA_ID_INVALID)
5962 {
5963 PVMSVGA3DSURFACE pSurface;
5964 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, paVertexBuffer[i].sid, &pSurface);
5965 AssertRCReturn(rc, rc);
5966
5967 if (pSurface->pBackendSurface == NULL)
5968 {
5969 /* Create the resource and initialize it with the current surface data. */
5970 rc = vmsvga3dBackSurfaceCreateBuffer(pThisCC, pDXContext, pSurface);
5971 AssertRCReturn(rc, rc);
5972 }
5973
5974 Assert(pSurface->pBackendSurface->u.pBuffer);
5975 paResources[idxVertexBuffer] = pSurface->pBackendSurface->u.pBuffer;
5976 paStride[idxVertexBuffer] = paVertexBuffer[i].stride;
5977 paOffset[idxVertexBuffer] = paVertexBuffer[i].offset;
5978 }
5979 else
5980 {
5981 paResources[idxVertexBuffer] = NULL;
5982 paStride[idxVertexBuffer] = 0;
5983 paOffset[idxVertexBuffer] = 0;
5984 }
5985 }
5986
5987 pDevice->pImmediateContext->IASetVertexBuffers(startBuffer, cVertexBuffer,
5988 &paResources[startBuffer], &paStride[startBuffer], &paOffset[startBuffer]);
5989
5990 return VINF_SUCCESS;
5991}
5992
5993
5994static DECLCALLBACK(int) vmsvga3dBackDXSetIndexBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSurfaceId sid, SVGA3dSurfaceFormat format, uint32_t offset)
5995{
5996 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5997 RT_NOREF(pBackend);
5998
5999 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6000 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6001
6002 /* Get corresponding resource. Create the buffer if does not yet exist. */
6003 ID3D11Buffer *pResource;
6004 DXGI_FORMAT enmDxgiFormat;
6005
6006 if (sid != SVGA_ID_INVALID)
6007 {
6008 PVMSVGA3DSURFACE pSurface;
6009 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
6010 AssertRCReturn(rc, rc);
6011
6012 if (pSurface->pBackendSurface == NULL)
6013 {
6014 /* Create the resource and initialize it with the current surface data. */
6015 rc = vmsvga3dBackSurfaceCreateBuffer(pThisCC, pDXContext, pSurface);
6016 AssertRCReturn(rc, rc);
6017 }
6018
6019 pResource = pSurface->pBackendSurface->u.pBuffer;
6020 enmDxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(format);
6021 AssertReturn(enmDxgiFormat == DXGI_FORMAT_R16_UINT || enmDxgiFormat == DXGI_FORMAT_R32_UINT, VERR_INVALID_PARAMETER);
6022 }
6023 else
6024 {
6025 pResource = NULL;
6026 enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
6027 }
6028
6029 pDevice->pImmediateContext->IASetIndexBuffer(pResource, enmDxgiFormat, offset);
6030 return VINF_SUCCESS;
6031}
6032
6033static D3D11_PRIMITIVE_TOPOLOGY dxTopology(SVGA3dPrimitiveType primitiveType)
6034{
6035 static D3D11_PRIMITIVE_TOPOLOGY const aD3D11PrimitiveTopology[SVGA3D_PRIMITIVE_MAX] =
6036 {
6037 D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED,
6038 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
6039 D3D11_PRIMITIVE_TOPOLOGY_POINTLIST,
6040 D3D11_PRIMITIVE_TOPOLOGY_LINELIST,
6041 D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP,
6042 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
6043 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, /* SVGA3D_PRIMITIVE_TRIANGLEFAN: No FAN in D3D11. */
6044 D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ,
6045 D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ,
6046 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ,
6047 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ,
6048 D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST,
6049 D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST,
6050 D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST,
6051 D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST,
6052 D3D11_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST,
6053 D3D11_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST,
6054 D3D11_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST,
6055 D3D11_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST,
6056 D3D11_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST,
6057 D3D11_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST,
6058 D3D11_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST,
6059 D3D11_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST,
6060 D3D11_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST,
6061 D3D11_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST,
6062 D3D11_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST,
6063 D3D11_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST,
6064 D3D11_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST,
6065 D3D11_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST,
6066 D3D11_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST,
6067 D3D11_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST,
6068 D3D11_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST,
6069 D3D11_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST,
6070 D3D11_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST,
6071 D3D11_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST,
6072 D3D11_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST,
6073 D3D11_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST,
6074 D3D11_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST,
6075 D3D11_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST,
6076 D3D11_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST,
6077 D3D11_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST,
6078 D3D11_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST,
6079 D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST,
6080 };
6081 return aD3D11PrimitiveTopology[primitiveType];
6082}
6083
6084static DECLCALLBACK(int) vmsvga3dBackDXSetTopology(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dPrimitiveType topology)
6085{
6086 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6087 RT_NOREF(pBackend);
6088
6089 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6090 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6091
6092 D3D11_PRIMITIVE_TOPOLOGY const enmTopology = dxTopology(topology);
6093 pDevice->pImmediateContext->IASetPrimitiveTopology(enmTopology);
6094 return VINF_SUCCESS;
6095}
6096
6097
6098static int dxSetRenderTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6099{
6100 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6101 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6102
6103 ID3D11RenderTargetView *apRenderTargetViews[SVGA3D_MAX_RENDER_TARGETS];
6104 RT_ZERO(apRenderTargetViews);
6105 for (uint32_t i = 0; i < SVGA3D_MAX_RENDER_TARGETS; ++i)
6106 {
6107 SVGA3dRenderTargetViewId const renderTargetViewId = pDXContext->svgaDXContext.renderState.renderTargetViewIds[i];
6108 if (renderTargetViewId != SVGA3D_INVALID_ID)
6109 {
6110 ASSERT_GUEST_RETURN(renderTargetViewId < pDXContext->pBackendDXContext->cRenderTargetView, VERR_INVALID_PARAMETER);
6111 apRenderTargetViews[i] = pDXContext->pBackendDXContext->paRenderTargetView[renderTargetViewId].u.pRenderTargetView;
6112 }
6113 }
6114
6115 ID3D11DepthStencilView *pDepthStencilView = NULL;
6116 SVGA3dDepthStencilViewId const depthStencilViewId = pDXContext->svgaDXContext.renderState.depthStencilViewId;
6117 if (depthStencilViewId != SVGA_ID_INVALID)
6118 pDepthStencilView = pDXContext->pBackendDXContext->paDepthStencilView[depthStencilViewId].u.pDepthStencilView;
6119
6120 pDevice->pImmediateContext->OMSetRenderTargets(SVGA3D_MAX_RENDER_TARGETS,
6121 apRenderTargetViews,
6122 pDepthStencilView);
6123 return VINF_SUCCESS;
6124}
6125
6126
6127static DECLCALLBACK(int) vmsvga3dBackDXSetRenderTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, uint32_t cRenderTargetViewId, SVGA3dRenderTargetViewId const *paRenderTargetViewId)
6128{
6129 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6130 RT_NOREF(pBackend);
6131
6132 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6133 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6134
6135 RT_NOREF(depthStencilViewId, cRenderTargetViewId, paRenderTargetViewId);
6136
6137 return VINF_SUCCESS;
6138}
6139
6140
6141static DECLCALLBACK(int) vmsvga3dBackDXSetBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dBlendStateId blendId, float const blendFactor[4], uint32_t sampleMask)
6142{
6143 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6144 RT_NOREF(pBackend);
6145
6146 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6147 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6148
6149 if (blendId != SVGA3D_INVALID_ID)
6150 {
6151 ID3D11BlendState *pBlendState = pDXContext->pBackendDXContext->papBlendState[blendId];
6152 pDevice->pImmediateContext->OMSetBlendState(pBlendState, blendFactor, sampleMask);
6153 }
6154 else
6155 pDevice->pImmediateContext->OMSetBlendState(NULL, NULL, 0);
6156
6157 return VINF_SUCCESS;
6158}
6159
6160
6161static DECLCALLBACK(int) vmsvga3dBackDXSetDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId, uint32_t stencilRef)
6162{
6163 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6164 RT_NOREF(pBackend);
6165
6166 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6167 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6168
6169 if (depthStencilId != SVGA3D_INVALID_ID)
6170 {
6171 ID3D11DepthStencilState *pDepthStencilState = pDXContext->pBackendDXContext->papDepthStencilState[depthStencilId];
6172 pDevice->pImmediateContext->OMSetDepthStencilState(pDepthStencilState, stencilRef);
6173 }
6174 else
6175 pDevice->pImmediateContext->OMSetDepthStencilState(NULL, 0);
6176
6177 return VINF_SUCCESS;
6178}
6179
6180
6181static DECLCALLBACK(int) vmsvga3dBackDXSetRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId)
6182{
6183 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6184 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6185 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6186
6187 RT_NOREF(pBackend);
6188
6189 if (rasterizerId != SVGA3D_INVALID_ID)
6190 {
6191 ID3D11RasterizerState *pRasterizerState = pDXContext->pBackendDXContext->papRasterizerState[rasterizerId];
6192 pDevice->pImmediateContext->RSSetState(pRasterizerState);
6193 }
6194 else
6195 pDevice->pImmediateContext->RSSetState(NULL);
6196
6197 return VINF_SUCCESS;
6198}
6199
6200
6201static DECLCALLBACK(int) vmsvga3dBackDXDefineQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6202{
6203 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6204
6205 RT_NOREF(pBackend, pDXContext);
6206 AssertFailed(); /** @todo Implement */
6207 return VERR_NOT_IMPLEMENTED;
6208}
6209
6210
6211static DECLCALLBACK(int) vmsvga3dBackDXDestroyQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6212{
6213 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6214
6215 RT_NOREF(pBackend, pDXContext);
6216 AssertFailed(); /** @todo Implement */
6217 return VERR_NOT_IMPLEMENTED;
6218}
6219
6220
6221static DECLCALLBACK(int) vmsvga3dBackDXBindQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6222{
6223 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6224
6225 RT_NOREF(pBackend, pDXContext);
6226 AssertFailed(); /** @todo Implement */
6227 return VERR_NOT_IMPLEMENTED;
6228}
6229
6230
6231static DECLCALLBACK(int) vmsvga3dBackDXSetQueryOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6232{
6233 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6234
6235 RT_NOREF(pBackend, pDXContext);
6236 AssertFailed(); /** @todo Implement */
6237 return VERR_NOT_IMPLEMENTED;
6238}
6239
6240
6241static DECLCALLBACK(int) vmsvga3dBackDXBeginQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6242{
6243 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6244
6245 RT_NOREF(pBackend, pDXContext);
6246 AssertFailed(); /** @todo Implement */
6247 return VERR_NOT_IMPLEMENTED;
6248}
6249
6250
6251static DECLCALLBACK(int) vmsvga3dBackDXEndQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6252{
6253 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6254
6255 RT_NOREF(pBackend, pDXContext);
6256 AssertFailed(); /** @todo Implement */
6257 return VERR_NOT_IMPLEMENTED;
6258}
6259
6260
6261static DECLCALLBACK(int) vmsvga3dBackDXReadbackQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6262{
6263 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6264
6265 RT_NOREF(pBackend, pDXContext);
6266 AssertFailed(); /** @todo Implement */
6267 return VERR_NOT_IMPLEMENTED;
6268}
6269
6270
6271static DECLCALLBACK(int) vmsvga3dBackDXSetPredication(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6272{
6273 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6274
6275 RT_NOREF(pBackend, pDXContext);
6276 AssertFailed(); /** @todo Implement */
6277 return VERR_NOT_IMPLEMENTED;
6278}
6279
6280
6281static DECLCALLBACK(int) vmsvga3dBackDXSetSOTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t cSOTarget, SVGA3dSoTarget const *paSoTarget)
6282{
6283 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6284 RT_NOREF(pBackend);
6285
6286 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6287 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6288
6289 /* For each paSoTarget[i]:
6290 * If the stream outout buffer object does not exist then create it.
6291 * If the surface has been updated by the guest then update the buffer object.
6292 * Use SOSetTargets to set the buffers.
6293 */
6294
6295 ID3D11Buffer *paResource[SVGA3D_DX_MAX_SOTARGETS];
6296 UINT paOffset[SVGA3D_DX_MAX_SOTARGETS];
6297
6298 /* Always re-bind all 4 SO targets. They can be NULL. */
6299 for (uint32_t i = 0; i < SVGA3D_DX_MAX_SOTARGETS; ++i)
6300 {
6301 /* Get corresponding resource. Create the buffer if does not yet exist. */
6302 if (i < cSOTarget && paSoTarget[i].sid != SVGA_ID_INVALID)
6303 {
6304 PVMSVGA3DSURFACE pSurface;
6305 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, paSoTarget[i].sid, &pSurface);
6306 AssertRCReturn(rc, rc);
6307
6308 if (pSurface->pBackendSurface == NULL)
6309 {
6310 /* Create the resource. */
6311 rc = vmsvga3dBackSurfaceCreateSoBuffer(pThisCC, pDXContext, pSurface);
6312 AssertRCReturn(rc, rc);
6313 }
6314
6315 /** @todo How paSoTarget[i].sizeInBytes is used? Maybe when the buffer is created? */
6316 paResource[i] = pSurface->pBackendSurface->u.pBuffer;
6317 paOffset[i] = paSoTarget[i].offset;
6318 }
6319 else
6320 {
6321 paResource[i] = NULL;
6322 paOffset[i] = 0;
6323 }
6324 }
6325
6326 pDevice->pImmediateContext->SOSetTargets(SVGA3D_DX_MAX_SOTARGETS, paResource, paOffset);
6327
6328 pDXContext->pBackendDXContext->cSOTarget = cSOTarget;
6329
6330 return VINF_SUCCESS;
6331}
6332
6333
6334static DECLCALLBACK(int) vmsvga3dBackDXSetViewports(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t cViewport, SVGA3dViewport const *paViewport)
6335{
6336 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6337 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6338 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6339
6340 RT_NOREF(pBackend);
6341
6342 /* D3D11_VIEWPORT is identical to SVGA3dViewport. */
6343 D3D11_VIEWPORT *pViewports = (D3D11_VIEWPORT *)paViewport;
6344
6345 pDevice->pImmediateContext->RSSetViewports(cViewport, pViewports);
6346 return VINF_SUCCESS;
6347}
6348
6349
6350static DECLCALLBACK(int) vmsvga3dBackDXSetScissorRects(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t cRect, SVGASignedRect const *paRect)
6351{
6352 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6353 RT_NOREF(pBackend);
6354
6355 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6356 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6357
6358 /* D3D11_RECT is identical to SVGASignedRect. */
6359 D3D11_RECT *pRects = (D3D11_RECT *)paRect;
6360
6361 pDevice->pImmediateContext->RSSetScissorRects(cRect, pRects);
6362 return VINF_SUCCESS;
6363}
6364
6365
6366static DECLCALLBACK(int) vmsvga3dBackDXClearRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGA3dRGBAFloat const *pRGBA)
6367{
6368 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6369 RT_NOREF(pBackend);
6370
6371 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6372 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6373
6374 DXVIEW *pDXView = &pDXContext->pBackendDXContext->paRenderTargetView[renderTargetViewId];
6375 if (!pDXView->u.pRenderTargetView)
6376 {
6377//DEBUG_BREAKPOINT_TEST();
6378 /* (Re-)create the render target view, because a creation of a view is deferred until a draw or a clear call. */
6379 SVGACOTableDXRTViewEntry const *pEntry = &pDXContext->cot.paRTView[renderTargetViewId];
6380 int rc = dxDefineRenderTargetView(pThisCC, pDXContext, renderTargetViewId, pEntry);
6381 AssertRCReturn(rc, rc);
6382 }
6383 pDevice->pImmediateContext->ClearRenderTargetView(pDXView->u.pRenderTargetView, pRGBA->value);
6384 return VINF_SUCCESS;
6385}
6386
6387
6388static DECLCALLBACK(int) vmsvga3dBackDXClearDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t flags, SVGA3dDepthStencilViewId depthStencilViewId, float depth, uint8_t stencil)
6389{
6390 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6391 RT_NOREF(pBackend);
6392
6393 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6394 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6395
6396 DXVIEW *pDXView = &pDXContext->pBackendDXContext->paDepthStencilView[depthStencilViewId];
6397 if (!pDXView->u.pDepthStencilView)
6398 {
6399//DEBUG_BREAKPOINT_TEST();
6400 /* (Re-)create the depth stencil view, because a creation of a view is deferred until a draw or a clear call. */
6401 SVGACOTableDXDSViewEntry const *pEntry = &pDXContext->cot.paDSView[depthStencilViewId];
6402 int rc = dxDefineDepthStencilView(pThisCC, pDXContext, depthStencilViewId, pEntry);
6403 AssertRCReturn(rc, rc);
6404 }
6405 pDevice->pImmediateContext->ClearDepthStencilView(pDXView->u.pDepthStencilView, flags, depth, stencil);
6406 return VINF_SUCCESS;
6407}
6408
6409
6410static DECLCALLBACK(int) vmsvga3dBackDXPredCopyRegion(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSurfaceId dstSid, uint32_t dstSubResource, SVGA3dSurfaceId srcSid, uint32_t srcSubResource, SVGA3dCopyBox const *pBox)
6411{
6412 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6413 RT_NOREF(pBackend);
6414
6415 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6416 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6417
6418 PVMSVGA3DSURFACE pSrcSurface;
6419 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, srcSid, &pSrcSurface);
6420 AssertRCReturn(rc, rc);
6421
6422 PVMSVGA3DSURFACE pDstSurface;
6423 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, dstSid, &pDstSurface);
6424 AssertRCReturn(rc, rc);
6425
6426 if (pSrcSurface->pBackendSurface == NULL)
6427 {
6428 /* Create the resource. */
6429 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSrcSurface);
6430 AssertRCReturn(rc, rc);
6431 }
6432
6433 if (pDstSurface->pBackendSurface == NULL)
6434 {
6435 /* Create the resource. */
6436 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pDstSurface);
6437 AssertRCReturn(rc, rc);
6438 }
6439
6440 LogFunc(("cid %d: src cid %d%s -> dst cid %d%s\n",
6441 pDXContext->cid, pSrcSurface->idAssociatedContext,
6442 (pSrcSurface->surfaceFlags & SVGA3D_SURFACE_SCREENTARGET) ? " st" : "",
6443 pDstSurface->idAssociatedContext,
6444 (pDstSurface->surfaceFlags & SVGA3D_SURFACE_SCREENTARGET) ? " st" : ""));
6445
6446 /* Clip the box. */
6447 /** @todo Use [src|dst]SubResource to index p[Src|Dst]Surface->paMipmapLevels array directly. */
6448 uint32_t iSrcFace;
6449 uint32_t iSrcMipmap;
6450 vmsvga3dCalcMipmapAndFace(pSrcSurface->cLevels, srcSubResource, &iSrcMipmap, &iSrcFace);
6451
6452 uint32_t iDstFace;
6453 uint32_t iDstMipmap;
6454 vmsvga3dCalcMipmapAndFace(pDstSurface->cLevels, dstSubResource, &iDstMipmap, &iDstFace);
6455
6456 PVMSVGA3DMIPMAPLEVEL pSrcMipLevel;
6457 rc = vmsvga3dMipmapLevel(pSrcSurface, iSrcFace, iSrcMipmap, &pSrcMipLevel);
6458 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
6459
6460 PVMSVGA3DMIPMAPLEVEL pDstMipLevel;
6461 rc = vmsvga3dMipmapLevel(pDstSurface, iDstFace, iDstMipmap, &pDstMipLevel);
6462 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
6463
6464 SVGA3dCopyBox clipBox = *pBox;
6465 vmsvgaR3ClipCopyBox(&pSrcMipLevel->mipmapSize, &pDstMipLevel->mipmapSize, &clipBox);
6466
6467 UINT DstSubresource = dstSubResource;
6468 UINT DstX = clipBox.x;
6469 UINT DstY = clipBox.y;
6470 UINT DstZ = clipBox.z;
6471
6472 UINT SrcSubresource = srcSubResource;
6473 D3D11_BOX SrcBox;
6474 SrcBox.left = clipBox.srcx;
6475 SrcBox.top = clipBox.srcy;
6476 SrcBox.front = clipBox.srcz;
6477 SrcBox.right = clipBox.srcx + clipBox.w;
6478 SrcBox.bottom = clipBox.srcy + clipBox.h;
6479 SrcBox.back = clipBox.srcz + clipBox.d;
6480
6481 ID3D11Resource *pDstResource;
6482 ID3D11Resource *pSrcResource;
6483
6484 pDstResource = dxResource(pThisCC->svga.p3dState, pDstSurface, pDXContext);
6485 pSrcResource = dxResource(pThisCC->svga.p3dState, pSrcSurface, pDXContext);
6486
6487 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
6488 pSrcResource, SrcSubresource, &SrcBox);
6489
6490 pDstSurface->pBackendSurface->cidDrawing = pDXContext->cid;
6491 return VINF_SUCCESS;
6492}
6493
6494
6495static DECLCALLBACK(int) vmsvga3dBackDXPredCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6496{
6497 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6498
6499 RT_NOREF(pBackend, pDXContext);
6500 AssertFailed(); /** @todo Implement */
6501 return VERR_NOT_IMPLEMENTED;
6502}
6503
6504
6505static DECLCALLBACK(int) vmsvga3dBackDXPresentBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6506{
6507 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6508
6509 RT_NOREF(pBackend, pDXContext);
6510 AssertFailed(); /** @todo Implement */
6511 return VERR_NOT_IMPLEMENTED;
6512}
6513
6514
6515static DECLCALLBACK(int) vmsvga3dBackDXGenMips(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId)
6516{
6517 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6518 RT_NOREF(pBackend);
6519
6520 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6521 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6522
6523 ID3D11ShaderResourceView *pShaderResourceView = pDXContext->pBackendDXContext->paShaderResourceView[shaderResourceViewId].u.pShaderResourceView;
6524 AssertReturn(pShaderResourceView, VERR_INVALID_STATE);
6525
6526 SVGACOTableDXSRViewEntry const *pSRViewEntry = dxGetShaderResourceViewEntry(pDXContext, shaderResourceViewId);
6527 AssertReturn(pSRViewEntry, VERR_INVALID_STATE);
6528
6529 uint32_t const sid = pSRViewEntry->sid;
6530
6531 PVMSVGA3DSURFACE pSurface;
6532 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
6533 AssertRCReturn(rc, rc);
6534 AssertReturn(pSurface->pBackendSurface, VERR_INVALID_STATE);
6535
6536 pDevice->pImmediateContext->GenerateMips(pShaderResourceView);
6537
6538 pSurface->pBackendSurface->cidDrawing = pDXContext->cid;
6539 return VINF_SUCCESS;
6540}
6541
6542
6543static int dxDefineShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId, SVGACOTableDXSRViewEntry const *pEntry)
6544{
6545 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
6546 PVMSVGA3DSURFACE pSurface;
6547 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
6548 AssertRCReturn(rc, rc);
6549
6550 ID3D11ShaderResourceView *pShaderResourceView;
6551 DXVIEW *pView = &pDXContext->pBackendDXContext->paShaderResourceView[shaderResourceViewId];
6552 Assert(pView->u.pView == NULL);
6553
6554 if (pSurface->pBackendSurface == NULL)
6555 {
6556 /* Create the actual texture. */
6557 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSurface);
6558 AssertRCReturn(rc, rc);
6559 }
6560
6561 HRESULT hr = dxShaderResourceViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pShaderResourceView);
6562 AssertReturn(SUCCEEDED(hr), VERR_INVALID_STATE);
6563
6564 return dxViewInit(pView, pSurface, pDXContext, shaderResourceViewId, VMSVGA3D_VIEWTYPE_SHADERRESOURCE, pShaderResourceView);
6565}
6566
6567
6568static DECLCALLBACK(int) vmsvga3dBackDXDefineShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId, SVGACOTableDXSRViewEntry const *pEntry)
6569{
6570 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6571 RT_NOREF(pBackend);
6572
6573 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6574 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6575
6576 /** @todo Probably not necessary because SRVs are defined in setupPipeline. */
6577 return dxDefineShaderResourceView(pThisCC, pDXContext, shaderResourceViewId, pEntry);
6578}
6579
6580
6581static DECLCALLBACK(int) vmsvga3dBackDXDestroyShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId)
6582{
6583 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6584 RT_NOREF(pBackend);
6585
6586 return dxViewDestroy(&pDXContext->pBackendDXContext->paShaderResourceView[shaderResourceViewId]);
6587}
6588
6589
6590static int dxDefineRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGACOTableDXRTViewEntry const *pEntry)
6591{
6592 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
6593 PVMSVGA3DSURFACE pSurface;
6594 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
6595 AssertRCReturn(rc, rc);
6596
6597 DXVIEW *pView = &pDXContext->pBackendDXContext->paRenderTargetView[renderTargetViewId];
6598 Assert(pView->u.pView == NULL);
6599
6600 if (pSurface->pBackendSurface == NULL)
6601 {
6602 /* Create the actual texture. */
6603 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSurface);
6604 AssertRCReturn(rc, rc);
6605 }
6606
6607 ID3D11RenderTargetView *pRenderTargetView;
6608 HRESULT hr = dxRenderTargetViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pRenderTargetView);
6609 AssertReturn(SUCCEEDED(hr), VERR_INVALID_STATE);
6610
6611 return dxViewInit(pView, pSurface, pDXContext, renderTargetViewId, VMSVGA3D_VIEWTYPE_RENDERTARGET, pRenderTargetView);
6612}
6613
6614
6615static DECLCALLBACK(int) vmsvga3dBackDXDefineRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGACOTableDXRTViewEntry const *pEntry)
6616{
6617 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6618 RT_NOREF(pBackend);
6619
6620 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6621 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6622
6623 return dxDefineRenderTargetView(pThisCC, pDXContext, renderTargetViewId, pEntry);
6624}
6625
6626
6627static DECLCALLBACK(int) vmsvga3dBackDXDestroyRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId)
6628{
6629 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6630 RT_NOREF(pBackend);
6631
6632 return dxViewDestroy(&pDXContext->pBackendDXContext->paRenderTargetView[renderTargetViewId]);
6633}
6634
6635
6636static int dxDefineDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, SVGACOTableDXDSViewEntry const *pEntry)
6637{
6638 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
6639 PVMSVGA3DSURFACE pSurface;
6640 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
6641 AssertRCReturn(rc, rc);
6642
6643 DXVIEW *pView = &pDXContext->pBackendDXContext->paDepthStencilView[depthStencilViewId];
6644 Assert(pView->u.pView == NULL);
6645
6646 if ( pSurface->pBackendSurface != NULL
6647 && pDXContext->cid != pSurface->idAssociatedContext)
6648 {
6649 /* Supposed to be per context. Sometimes the guest reuses the texture in another context. */
6650 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
6651 }
6652
6653 if (pSurface->pBackendSurface == NULL)
6654 {
6655 /* Create the actual texture. */
6656 rc = vmsvga3dBackSurfaceCreateDepthStencilTexture(pThisCC, pDXContext, pSurface);
6657 AssertRCReturn(rc, rc);
6658 }
6659
6660 ID3D11DepthStencilView *pDepthStencilView;
6661 HRESULT hr = dxDepthStencilViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pDepthStencilView);
6662 AssertReturn(SUCCEEDED(hr), VERR_INVALID_STATE);
6663
6664 return dxViewInit(pView, pSurface, pDXContext, depthStencilViewId, VMSVGA3D_VIEWTYPE_DEPTHSTENCIL, pDepthStencilView);
6665}
6666
6667static DECLCALLBACK(int) vmsvga3dBackDXDefineDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, SVGACOTableDXDSViewEntry const *pEntry)
6668{
6669 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6670 RT_NOREF(pBackend);
6671
6672 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6673 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6674
6675 return dxDefineDepthStencilView(pThisCC, pDXContext, depthStencilViewId, pEntry);
6676}
6677
6678
6679static DECLCALLBACK(int) vmsvga3dBackDXDestroyDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId)
6680{
6681 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6682 RT_NOREF(pBackend);
6683
6684 return dxViewDestroy(&pDXContext->pBackendDXContext->paDepthStencilView[depthStencilViewId]);
6685}
6686
6687
6688static int dxDefineElementLayout(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId, SVGACOTableDXElementLayoutEntry const *pEntry)
6689{
6690 DXELEMENTLAYOUT *pDXElementLayout = &pDXContext->pBackendDXContext->paElementLayout[elementLayoutId];
6691 D3D_RELEASE(pDXElementLayout->pElementLayout);
6692
6693 /* Semantic name is not interpreted by D3D, therefore arbitrary names can be used
6694 * if they are consistent between the element layout and shader input signature.
6695 * "In general, data passed between pipeline stages is completely generic and is not uniquely
6696 * interpreted by the system; arbitrary semantics are allowed ..."
6697 *
6698 * However D3D runtime insists that "SemanticName string ("POSITIO1") cannot end with a number."
6699 *
6700 * System-Value semantics ("SV_*") between shaders require proper names of course.
6701 * But they are irrelevant for input attributes.
6702 */
6703 pDXElementLayout->cElementDesc = pEntry->numDescs;
6704 for (uint32_t i = 0; i < pEntry->numDescs; ++i)
6705 {
6706 D3D11_INPUT_ELEMENT_DESC *pDst = &pDXElementLayout->aElementDesc[i];
6707 SVGA3dInputElementDesc const *pSrc = &pEntry->descs[i];
6708 pDst->SemanticName = "ATTRIB";
6709 pDst->SemanticIndex = i; /// @todo 'pSrc->inputRegister' is unused, maybe it should somehow.
6710 pDst->Format = vmsvgaDXSurfaceFormat2Dxgi(pSrc->format);
6711 AssertReturn(pDst->Format != DXGI_FORMAT_UNKNOWN, VERR_NOT_IMPLEMENTED);
6712 pDst->InputSlot = pSrc->inputSlot;
6713 pDst->AlignedByteOffset = pSrc->alignedByteOffset;
6714 pDst->InputSlotClass = (D3D11_INPUT_CLASSIFICATION)pSrc->inputSlotClass;
6715 pDst->InstanceDataStepRate = pSrc->instanceDataStepRate;
6716 }
6717
6718 return VINF_SUCCESS;
6719}
6720
6721
6722static DECLCALLBACK(int) vmsvga3dBackDXDefineElementLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId, SVGACOTableDXElementLayoutEntry const *pEntry)
6723{
6724 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6725 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6726 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6727
6728 RT_NOREF(pBackend);
6729
6730 /* Not much can be done here because ID3D11Device::CreateInputLayout requires
6731 * a pShaderBytecodeWithInputSignature which is not known at this moment.
6732 * InputLayout object will be created in SVGA_3D_CMD_DX_SET_INPUT_LAYOUT.
6733 */
6734
6735 Assert(elementLayoutId == pEntry->elid);
6736
6737 return dxDefineElementLayout(pDXContext, elementLayoutId, pEntry);
6738}
6739
6740
6741static DECLCALLBACK(int) vmsvga3dBackDXDestroyElementLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6742{
6743 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6744
6745 RT_NOREF(pBackend, pDXContext);
6746 AssertFailed(); /** @todo Implement */
6747 return VERR_NOT_IMPLEMENTED;
6748}
6749
6750
6751static int dxDefineBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
6752 SVGA3dBlendStateId blendId, SVGACOTableDXBlendStateEntry const *pEntry)
6753{
6754 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6755 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6756
6757 HRESULT hr = dxBlendStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papBlendState[blendId]);
6758 if (SUCCEEDED(hr))
6759 return VINF_SUCCESS;
6760 return VERR_INVALID_STATE;
6761}
6762
6763static DECLCALLBACK(int) vmsvga3dBackDXDefineBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
6764 SVGA3dBlendStateId blendId, SVGACOTableDXBlendStateEntry const *pEntry)
6765{
6766 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6767 RT_NOREF(pBackend);
6768
6769 return dxDefineBlendState(pThisCC, pDXContext, blendId, pEntry);
6770}
6771
6772
6773static DECLCALLBACK(int) vmsvga3dBackDXDestroyBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6774{
6775 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6776
6777 RT_NOREF(pBackend, pDXContext);
6778 AssertFailed(); /** @todo Implement */
6779 return VERR_NOT_IMPLEMENTED;
6780}
6781
6782
6783static int dxDefineDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId, SVGACOTableDXDepthStencilEntry const *pEntry)
6784{
6785 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6786 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6787
6788 HRESULT hr = dxDepthStencilStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papDepthStencilState[depthStencilId]);
6789 if (SUCCEEDED(hr))
6790 return VINF_SUCCESS;
6791 return VERR_INVALID_STATE;
6792}
6793
6794
6795static DECLCALLBACK(int) vmsvga3dBackDXDefineDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId, SVGACOTableDXDepthStencilEntry const *pEntry)
6796{
6797 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6798 RT_NOREF(pBackend);
6799
6800 return dxDefineDepthStencilState(pThisCC, pDXContext, depthStencilId, pEntry);
6801}
6802
6803
6804static DECLCALLBACK(int) vmsvga3dBackDXDestroyDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6805{
6806 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6807
6808 RT_NOREF(pBackend, pDXContext);
6809 AssertFailed(); /** @todo Implement */
6810 return VERR_NOT_IMPLEMENTED;
6811}
6812
6813
6814static int dxDefineRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId, SVGACOTableDXRasterizerStateEntry const *pEntry)
6815{
6816 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6817 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6818
6819 HRESULT hr = dxRasterizerStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papRasterizerState[rasterizerId]);
6820 if (SUCCEEDED(hr))
6821 return VINF_SUCCESS;
6822 return VERR_INVALID_STATE;
6823}
6824
6825
6826static DECLCALLBACK(int) vmsvga3dBackDXDefineRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId, SVGACOTableDXRasterizerStateEntry const *pEntry)
6827{
6828 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6829 RT_NOREF(pBackend);
6830
6831 return dxDefineRasterizerState(pThisCC, pDXContext, rasterizerId, pEntry);
6832}
6833
6834
6835static DECLCALLBACK(int) vmsvga3dBackDXDestroyRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6836{
6837 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6838
6839 RT_NOREF(pBackend, pDXContext);
6840 AssertFailed(); /** @todo Implement */
6841 return VERR_NOT_IMPLEMENTED;
6842}
6843
6844
6845static int dxDefineSamplerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSamplerId samplerId, SVGACOTableDXSamplerEntry const *pEntry)
6846{
6847 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6848 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6849
6850 HRESULT hr = dxSamplerStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papSamplerState[samplerId]);
6851 if (SUCCEEDED(hr))
6852 return VINF_SUCCESS;
6853 return VERR_INVALID_STATE;
6854}
6855
6856
6857static DECLCALLBACK(int) vmsvga3dBackDXDefineSamplerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSamplerId samplerId, SVGACOTableDXSamplerEntry const *pEntry)
6858{
6859 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6860 RT_NOREF(pBackend);
6861
6862 return dxDefineSamplerState(pThisCC, pDXContext, samplerId, pEntry);
6863}
6864
6865
6866static DECLCALLBACK(int) vmsvga3dBackDXDestroySamplerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6867{
6868 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6869
6870 RT_NOREF(pBackend, pDXContext);
6871 AssertFailed(); /** @todo Implement */
6872 return VERR_NOT_IMPLEMENTED;
6873}
6874
6875
6876
6877static int dxDefineShader(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, SVGACOTableDXShaderEntry const *pEntry)
6878{
6879 /** @todo A common approach for creation of COTable backend objects: runtime, empty DX COTable, live DX COTable. */
6880 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
6881 Assert(pDXShader->enmShaderType == SVGA3D_SHADERTYPE_INVALID);
6882
6883 /* Init the backend shader structure, if the shader has not been created yet. */
6884 pDXShader->enmShaderType = pEntry->type;
6885 pDXShader->pShader = NULL;
6886 pDXShader->soid = SVGA_ID_INVALID;
6887
6888 return VINF_SUCCESS;
6889}
6890
6891
6892static int dxDestroyShader(DXSHADER *pDXShader)
6893{
6894 pDXShader->enmShaderType = SVGA3D_SHADERTYPE_INVALID;
6895 D3D_RELEASE(pDXShader->pShader);
6896 RTMemFree(pDXShader->pvDXBC);
6897 pDXShader->pvDXBC = NULL;
6898 pDXShader->cbDXBC = 0;
6899 pDXShader->soid = SVGA_ID_INVALID;
6900 return VINF_SUCCESS;
6901}
6902
6903
6904static DECLCALLBACK(int) vmsvga3dBackDXDefineShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, SVGACOTableDXShaderEntry const *pEntry)
6905{
6906 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6907 RT_NOREF(pBackend);
6908
6909 return dxDefineShader(pDXContext, shaderId, pEntry);
6910}
6911
6912
6913static DECLCALLBACK(int) vmsvga3dBackDXDestroyShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId)
6914{
6915 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6916 RT_NOREF(pBackend);
6917
6918 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
6919 dxDestroyShader(pDXShader);
6920
6921 return VINF_SUCCESS;
6922}
6923
6924
6925static DECLCALLBACK(int) vmsvga3dBackDXBindShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, DXShaderInfo const *pShaderInfo)
6926{
6927 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6928 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6929 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6930
6931 RT_NOREF(pBackend);
6932
6933 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
6934 if (pDXShader->pvDXBC)
6935 {
6936 /* New DXBC code and new shader must be created. */
6937 D3D_RELEASE(pDXShader->pShader);
6938 RTMemFree(pDXShader->pvDXBC);
6939 pDXShader->pvDXBC = NULL;
6940 pDXShader->cbDXBC = 0;
6941 }
6942
6943 pDXShader->shaderInfo = *pShaderInfo;
6944
6945 return VINF_SUCCESS;
6946}
6947
6948
6949static DECLCALLBACK(int) vmsvga3dBackDXDefineStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid, SVGACOTableDXStreamOutputEntry const *pEntry)
6950{
6951 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6952 RT_NOREF(pBackend);
6953
6954 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
6955 dxDestroyStreamOutput(pDXStreamOutput);
6956
6957 return dxDefineStreamOutput(pDXContext, soid, pEntry);
6958}
6959
6960
6961static DECLCALLBACK(int) vmsvga3dBackDXDestroyStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid)
6962{
6963 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6964 RT_NOREF(pBackend);
6965
6966 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
6967 dxDestroyStreamOutput(pDXStreamOutput);
6968
6969 return VINF_SUCCESS;
6970}
6971
6972
6973static DECLCALLBACK(int) vmsvga3dBackDXSetStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid)
6974{
6975 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6976 RT_NOREF(pBackend, pDXContext, soid);
6977
6978 return VINF_SUCCESS;
6979}
6980
6981
6982static int dxCOTableRealloc(void **ppvCOTable, uint32_t *pcCOTable, uint32_t cbEntry, uint32_t cEntries, uint32_t cValidEntries)
6983{
6984 uint32_t const cCOTableCurrent = *pcCOTable;
6985
6986 if (*pcCOTable != cEntries)
6987 {
6988 /* Grow/shrink the array. */
6989 if (cEntries)
6990 {
6991 void *pvNew = RTMemRealloc(*ppvCOTable, cEntries * cbEntry);
6992 AssertReturn(pvNew, VERR_NO_MEMORY);
6993 *ppvCOTable = pvNew;
6994 }
6995 else
6996 {
6997 RTMemFree(*ppvCOTable);
6998 *ppvCOTable = NULL;
6999 }
7000
7001 *pcCOTable = cEntries;
7002 }
7003
7004 if (*ppvCOTable)
7005 {
7006 uint32_t const cEntriesToKeep = RT_MIN(cCOTableCurrent, cValidEntries);
7007 memset((uint8_t *)(*ppvCOTable) + cEntriesToKeep * cbEntry, 0, (cEntries - cEntriesToKeep) * cbEntry);
7008 }
7009
7010 return VINF_SUCCESS;
7011}
7012
7013static DECLCALLBACK(int) vmsvga3dBackDXSetCOTable(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableType type, uint32_t cValidEntries)
7014{
7015 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7016 RT_NOREF(pBackend);
7017
7018 VMSVGA3DBACKENDDXCONTEXT *pBackendDXContext = pDXContext->pBackendDXContext;
7019
7020 int rc = VINF_SUCCESS;
7021
7022 /*
7023 * 1) Release current backend table, if exists;
7024 * 2) Reallocate memory for the new backend table;
7025 * 3) If cValidEntries is not zero, then re-define corresponding backend table elements.
7026 */
7027 switch (type)
7028 {
7029 case SVGA_COTABLE_RTVIEW:
7030 /* Clear current entries. */
7031 if (pBackendDXContext->paRenderTargetView)
7032 {
7033 for (uint32_t i = 0; i < pBackendDXContext->cRenderTargetView; ++i)
7034 {
7035 DXVIEW *pDXView = &pBackendDXContext->paRenderTargetView[i];
7036 if (i < cValidEntries)
7037 dxViewRemoveFromList(pDXView); /* Remove from list because DXVIEW array will be reallocated. */
7038 else
7039 dxViewDestroy(pDXView);
7040 }
7041 }
7042
7043 rc = dxCOTableRealloc((void **)&pBackendDXContext->paRenderTargetView, &pBackendDXContext->cRenderTargetView,
7044 sizeof(pBackendDXContext->paRenderTargetView[0]), pDXContext->cot.cRTView, cValidEntries);
7045 AssertRCBreak(rc);
7046
7047 for (uint32_t i = 0; i < cValidEntries; ++i)
7048 {
7049 SVGACOTableDXRTViewEntry const *pEntry = &pDXContext->cot.paRTView[i];
7050 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7051 continue; /* Skip uninitialized entry. */
7052
7053 /* Define views which were not defined yet in backend. */
7054 DXVIEW *pDXView = &pBackendDXContext->paRenderTargetView[i];
7055 /** @todo Verify that the pEntry content still corresponds to the view. */
7056 if (pDXView->u.pView)
7057 dxViewAddToList(pThisCC, pDXView);
7058 else if (pDXView->enmViewType == VMSVGA3D_VIEWTYPE_NONE)
7059 dxDefineRenderTargetView(pThisCC, pDXContext, i, pEntry);
7060 }
7061 break;
7062 case SVGA_COTABLE_DSVIEW:
7063 if (pBackendDXContext->paDepthStencilView)
7064 {
7065 for (uint32_t i = 0; i < pBackendDXContext->cDepthStencilView; ++i)
7066 {
7067 DXVIEW *pDXView = &pBackendDXContext->paDepthStencilView[i];
7068 if (i < cValidEntries)
7069 dxViewRemoveFromList(pDXView); /* Remove from list because DXVIEW array will be reallocated. */
7070 else
7071 dxViewDestroy(pDXView);
7072 }
7073 }
7074
7075 rc = dxCOTableRealloc((void **)&pBackendDXContext->paDepthStencilView, &pBackendDXContext->cDepthStencilView,
7076 sizeof(pBackendDXContext->paDepthStencilView[0]), pDXContext->cot.cDSView, cValidEntries);
7077 AssertRCBreak(rc);
7078
7079 for (uint32_t i = 0; i < cValidEntries; ++i)
7080 {
7081 SVGACOTableDXDSViewEntry const *pEntry = &pDXContext->cot.paDSView[i];
7082 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7083 continue; /* Skip uninitialized entry. */
7084
7085 /* Define views which were not defined yet in backend. */
7086 DXVIEW *pDXView = &pBackendDXContext->paDepthStencilView[i];
7087 /** @todo Verify that the pEntry content still corresponds to the view. */
7088 if (pDXView->u.pView)
7089 dxViewAddToList(pThisCC, pDXView);
7090 else if (pDXView->enmViewType == VMSVGA3D_VIEWTYPE_NONE)
7091 dxDefineDepthStencilView(pThisCC, pDXContext, i, pEntry);
7092 }
7093 break;
7094 case SVGA_COTABLE_SRVIEW:
7095 if (pBackendDXContext->paShaderResourceView)
7096 {
7097 for (uint32_t i = 0; i < pBackendDXContext->cShaderResourceView; ++i)
7098 {
7099 DXVIEW *pDXView = &pBackendDXContext->paShaderResourceView[i];
7100 if (i < cValidEntries)
7101 dxViewRemoveFromList(pDXView); /* Remove from list because DXVIEW array will be reallocated. */
7102 else
7103 dxViewDestroy(pDXView);
7104 }
7105 }
7106
7107 rc = dxCOTableRealloc((void **)&pBackendDXContext->paShaderResourceView, &pBackendDXContext->cShaderResourceView,
7108 sizeof(pBackendDXContext->paShaderResourceView[0]), pDXContext->cot.cSRView, cValidEntries);
7109 AssertRCBreak(rc);
7110
7111 for (uint32_t i = 0; i < cValidEntries; ++i)
7112 {
7113 SVGACOTableDXSRViewEntry const *pEntry = &pDXContext->cot.paSRView[i];
7114 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7115 continue; /* Skip uninitialized entry. */
7116
7117 /* Define views which were not defined yet in backend. */
7118 DXVIEW *pDXView = &pBackendDXContext->paShaderResourceView[i];
7119 /** @todo Verify that the pEntry content still corresponds to the view. */
7120 if (pDXView->u.pView)
7121 dxViewAddToList(pThisCC, pDXView);
7122 else if (pDXView->enmViewType == VMSVGA3D_VIEWTYPE_NONE)
7123 dxDefineShaderResourceView(pThisCC, pDXContext, i, pEntry);
7124 }
7125 break;
7126 case SVGA_COTABLE_ELEMENTLAYOUT:
7127 if (pBackendDXContext->paElementLayout)
7128 {
7129 for (uint32_t i = cValidEntries; i < pBackendDXContext->cElementLayout; ++i)
7130 D3D_RELEASE(pBackendDXContext->paElementLayout[i].pElementLayout);
7131 }
7132
7133 rc = dxCOTableRealloc((void **)&pBackendDXContext->paElementLayout, &pBackendDXContext->cElementLayout,
7134 sizeof(pBackendDXContext->paElementLayout[0]), pDXContext->cot.cElementLayout, cValidEntries);
7135 AssertRCBreak(rc);
7136
7137 for (uint32_t i = 0; i < cValidEntries; ++i)
7138 {
7139 SVGACOTableDXElementLayoutEntry const *pEntry = &pDXContext->cot.paElementLayout[i];
7140 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7141 continue; /* Skip uninitialized entry. */
7142
7143 dxDefineElementLayout(pDXContext, i, pEntry);
7144 }
7145 break;
7146 case SVGA_COTABLE_BLENDSTATE:
7147 if (pBackendDXContext->papBlendState)
7148 {
7149 for (uint32_t i = cValidEntries; i < pBackendDXContext->cBlendState; ++i)
7150 D3D_RELEASE(pBackendDXContext->papBlendState[i]);
7151 }
7152
7153 rc = dxCOTableRealloc((void **)&pBackendDXContext->papBlendState, &pBackendDXContext->cBlendState,
7154 sizeof(pBackendDXContext->papBlendState[0]), pDXContext->cot.cBlendState, cValidEntries);
7155 AssertRCBreak(rc);
7156
7157 for (uint32_t i = 0; i < cValidEntries; ++i)
7158 {
7159 SVGACOTableDXBlendStateEntry const *pEntry = &pDXContext->cot.paBlendState[i];
7160 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7161 continue; /* Skip uninitialized entry. */
7162
7163 dxDefineBlendState(pThisCC, pDXContext, i, pEntry);
7164 }
7165 break;
7166 case SVGA_COTABLE_DEPTHSTENCIL:
7167 if (pBackendDXContext->papDepthStencilState)
7168 {
7169 for (uint32_t i = cValidEntries; i < pBackendDXContext->cDepthStencilState; ++i)
7170 D3D_RELEASE(pBackendDXContext->papDepthStencilState[i]);
7171 }
7172
7173 rc = dxCOTableRealloc((void **)&pBackendDXContext->papDepthStencilState, &pBackendDXContext->cDepthStencilState,
7174 sizeof(pBackendDXContext->papDepthStencilState[0]), pDXContext->cot.cDepthStencil, cValidEntries);
7175 AssertRCBreak(rc);
7176
7177 for (uint32_t i = 0; i < cValidEntries; ++i)
7178 {
7179 SVGACOTableDXDepthStencilEntry const *pEntry = &pDXContext->cot.paDepthStencil[i];
7180 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7181 continue; /* Skip uninitialized entry. */
7182
7183 dxDefineDepthStencilState(pThisCC, pDXContext, i, pEntry);
7184 }
7185 break;
7186 case SVGA_COTABLE_RASTERIZERSTATE:
7187 if (pBackendDXContext->papRasterizerState)
7188 {
7189 for (uint32_t i = cValidEntries; i < pBackendDXContext->cRasterizerState; ++i)
7190 D3D_RELEASE(pBackendDXContext->papRasterizerState[i]);
7191 }
7192
7193 rc = dxCOTableRealloc((void **)&pBackendDXContext->papRasterizerState, &pBackendDXContext->cRasterizerState,
7194 sizeof(pBackendDXContext->papRasterizerState[0]), pDXContext->cot.cRasterizerState, cValidEntries);
7195 AssertRCBreak(rc);
7196
7197 for (uint32_t i = 0; i < cValidEntries; ++i)
7198 {
7199 SVGACOTableDXRasterizerStateEntry const *pEntry = &pDXContext->cot.paRasterizerState[i];
7200 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7201 continue; /* Skip uninitialized entry. */
7202
7203 dxDefineRasterizerState(pThisCC, pDXContext, i, pEntry);
7204 }
7205 break;
7206 case SVGA_COTABLE_SAMPLER:
7207 if (pBackendDXContext->papSamplerState)
7208 {
7209 for (uint32_t i = cValidEntries; i < pBackendDXContext->cSamplerState; ++i)
7210 D3D_RELEASE(pBackendDXContext->papSamplerState[i]);
7211 }
7212
7213 rc = dxCOTableRealloc((void **)&pBackendDXContext->papSamplerState, &pBackendDXContext->cSamplerState,
7214 sizeof(pBackendDXContext->papSamplerState[0]), pDXContext->cot.cSampler, cValidEntries);
7215 AssertRCBreak(rc);
7216
7217 for (uint32_t i = 0; i < cValidEntries; ++i)
7218 {
7219 SVGACOTableDXSamplerEntry const *pEntry = &pDXContext->cot.paSampler[i];
7220 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7221 continue; /* Skip uninitialized entry. */
7222
7223 dxDefineSamplerState(pThisCC, pDXContext, i, pEntry);
7224 }
7225 break;
7226 case SVGA_COTABLE_STREAMOUTPUT:
7227 if (pBackendDXContext->paStreamOutput)
7228 {
7229 for (uint32_t i = cValidEntries; i < pBackendDXContext->cStreamOutput; ++i)
7230 dxDestroyStreamOutput(&pBackendDXContext->paStreamOutput[i]);
7231 }
7232
7233 rc = dxCOTableRealloc((void **)&pBackendDXContext->paStreamOutput, &pBackendDXContext->cStreamOutput,
7234 sizeof(pBackendDXContext->paStreamOutput[0]), pDXContext->cot.cStreamOutput, cValidEntries);
7235 AssertRCBreak(rc);
7236
7237 for (uint32_t i = 0; i < cValidEntries; ++i)
7238 {
7239 SVGACOTableDXStreamOutputEntry const *pEntry = &pDXContext->cot.paStreamOutput[i];
7240 /** @todo The caller must verify the COTable content using same rules as when a new entry is defined. */
7241 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7242 continue; /* Skip uninitialized entry. */
7243
7244 dxDefineStreamOutput(pDXContext, i, pEntry);
7245 }
7246 break;
7247 case SVGA_COTABLE_DXQUERY:
7248 if (pBackendDXContext->papQuery)
7249 {
7250 for (uint32_t i = cValidEntries; i < pBackendDXContext->cQuery; ++i)
7251 D3D_RELEASE(pBackendDXContext->papQuery[i]);
7252 }
7253
7254 rc = dxCOTableRealloc((void **)&pBackendDXContext->papQuery, &pBackendDXContext->cQuery,
7255 sizeof(pBackendDXContext->papQuery[0]), pDXContext->cot.cQuery, cValidEntries);
7256 AssertRCBreak(rc);
7257
7258 for (uint32_t i = 0; i < cValidEntries; ++i)
7259 {
7260 SVGACOTableDXQueryEntry const *pEntry = &pDXContext->cot.paQuery[i];
7261 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7262 continue; /* Skip uninitialized entry. */
7263
7264 AssertFailed(); /** @todo implement */
7265 }
7266 break;
7267 case SVGA_COTABLE_DXSHADER:
7268 if (pBackendDXContext->paShader)
7269 {
7270 /* Destroy the no longer used entries. */
7271 for (uint32_t i = cValidEntries; i < pBackendDXContext->cShader; ++i)
7272 dxDestroyShader(&pBackendDXContext->paShader[i]);
7273 }
7274
7275 rc = dxCOTableRealloc((void **)&pBackendDXContext->paShader, &pBackendDXContext->cShader,
7276 sizeof(pBackendDXContext->paShader[0]), pDXContext->cot.cShader, cValidEntries);
7277 AssertRCBreak(rc);
7278
7279 for (uint32_t i = 0; i < cValidEntries; ++i)
7280 {
7281 SVGACOTableDXShaderEntry const *pEntry = &pDXContext->cot.paShader[i];
7282 /** @todo The caller must verify the COTable content using same rules as when a new entry is defined. */
7283 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7284 continue; /* Skip uninitialized entry. */
7285
7286 /* Define shaders which were not defined yet in backend. */
7287 DXSHADER *pDXShader = &pBackendDXContext->paShader[i];
7288 if ( pEntry->type != SVGA3D_SHADERTYPE_INVALID
7289 && pDXShader->enmShaderType == SVGA3D_SHADERTYPE_INVALID)
7290 dxDefineShader(pDXContext, i, pEntry);
7291 else
7292 Assert(pEntry->type == pDXShader->enmShaderType);
7293
7294 }
7295 break;
7296 case SVGA_COTABLE_UAVIEW:
7297 AssertFailed(); /** @todo Implement */
7298 break;
7299 case SVGA_COTABLE_MAX: break; /* Compiler warning */
7300 }
7301 return rc;
7302}
7303
7304
7305static DECLCALLBACK(int) vmsvga3dBackDXBufferCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7306{
7307 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7308
7309 RT_NOREF(pBackend, pDXContext);
7310 AssertFailed(); /** @todo Implement */
7311 return VERR_NOT_IMPLEMENTED;
7312}
7313
7314
7315static DECLCALLBACK(int) vmsvga3dBackDXSurfaceCopyAndReadback(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7316{
7317 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7318
7319 RT_NOREF(pBackend, pDXContext);
7320 AssertFailed(); /** @todo Implement */
7321 return VERR_NOT_IMPLEMENTED;
7322}
7323
7324
7325static DECLCALLBACK(int) vmsvga3dBackDXMoveQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7326{
7327 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7328
7329 RT_NOREF(pBackend, pDXContext);
7330 AssertFailed(); /** @todo Implement */
7331 return VERR_NOT_IMPLEMENTED;
7332}
7333
7334
7335static DECLCALLBACK(int) vmsvga3dBackDXBindAllQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7336{
7337 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7338
7339 RT_NOREF(pBackend, pDXContext);
7340 AssertFailed(); /** @todo Implement */
7341 return VERR_NOT_IMPLEMENTED;
7342}
7343
7344
7345static DECLCALLBACK(int) vmsvga3dBackDXReadbackAllQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7346{
7347 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7348
7349 RT_NOREF(pBackend, pDXContext);
7350 AssertFailed(); /** @todo Implement */
7351 return VERR_NOT_IMPLEMENTED;
7352}
7353
7354
7355static DECLCALLBACK(int) vmsvga3dBackDXMobFence64(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7356{
7357 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7358
7359 RT_NOREF(pBackend, pDXContext);
7360 AssertFailed(); /** @todo Implement */
7361 return VERR_NOT_IMPLEMENTED;
7362}
7363
7364
7365static DECLCALLBACK(int) vmsvga3dBackDXBindAllShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7366{
7367 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7368
7369 RT_NOREF(pBackend, pDXContext);
7370 AssertFailed(); /** @todo Implement */
7371 return VERR_NOT_IMPLEMENTED;
7372}
7373
7374
7375static DECLCALLBACK(int) vmsvga3dBackDXHint(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7376{
7377 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7378
7379 RT_NOREF(pBackend, pDXContext);
7380 AssertFailed(); /** @todo Implement */
7381 return VERR_NOT_IMPLEMENTED;
7382}
7383
7384
7385static DECLCALLBACK(int) vmsvga3dBackDXBufferUpdate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7386{
7387 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7388
7389 RT_NOREF(pBackend, pDXContext);
7390 AssertFailed(); /** @todo Implement */
7391 return VERR_NOT_IMPLEMENTED;
7392}
7393
7394
7395static DECLCALLBACK(int) vmsvga3dBackDXSetVSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7396{
7397 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7398
7399 RT_NOREF(pBackend, pDXContext);
7400 AssertFailed(); /** @todo Implement */
7401 return VERR_NOT_IMPLEMENTED;
7402}
7403
7404
7405static DECLCALLBACK(int) vmsvga3dBackDXSetPSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7406{
7407 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7408
7409 RT_NOREF(pBackend, pDXContext);
7410 AssertFailed(); /** @todo Implement */
7411 return VERR_NOT_IMPLEMENTED;
7412}
7413
7414
7415static DECLCALLBACK(int) vmsvga3dBackDXSetGSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7416{
7417 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7418
7419 RT_NOREF(pBackend, pDXContext);
7420 AssertFailed(); /** @todo Implement */
7421 return VERR_NOT_IMPLEMENTED;
7422}
7423
7424
7425static DECLCALLBACK(int) vmsvga3dBackDXSetHSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7426{
7427 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7428
7429 RT_NOREF(pBackend, pDXContext);
7430 AssertFailed(); /** @todo Implement */
7431 return VERR_NOT_IMPLEMENTED;
7432}
7433
7434
7435static DECLCALLBACK(int) vmsvga3dBackDXSetDSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7436{
7437 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7438
7439 RT_NOREF(pBackend, pDXContext);
7440 AssertFailed(); /** @todo Implement */
7441 return VERR_NOT_IMPLEMENTED;
7442}
7443
7444
7445static DECLCALLBACK(int) vmsvga3dBackDXSetCSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7446{
7447 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7448
7449 RT_NOREF(pBackend, pDXContext);
7450 AssertFailed(); /** @todo Implement */
7451 return VERR_NOT_IMPLEMENTED;
7452}
7453
7454
7455static DECLCALLBACK(int) vmsvga3dBackDXCondBindAllShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7456{
7457 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7458
7459 RT_NOREF(pBackend, pDXContext);
7460 AssertFailed(); /** @todo Implement */
7461 return VERR_NOT_IMPLEMENTED;
7462}
7463
7464
7465static DECLCALLBACK(int) vmsvga3dBackScreenCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7466{
7467 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7468
7469 RT_NOREF(pBackend, pDXContext);
7470 AssertFailed(); /** @todo Implement */
7471 return VERR_NOT_IMPLEMENTED;
7472}
7473
7474
7475static DECLCALLBACK(int) vmsvga3dBackGrowOTable(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7476{
7477 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7478
7479 RT_NOREF(pBackend, pDXContext);
7480 AssertFailed(); /** @todo Implement */
7481 return VERR_NOT_IMPLEMENTED;
7482}
7483
7484
7485static DECLCALLBACK(int) vmsvga3dBackDXGrowCOTable(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7486{
7487 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7488
7489 RT_NOREF(pBackend, pDXContext);
7490 AssertFailed(); /** @todo Implement */
7491 return VERR_NOT_IMPLEMENTED;
7492}
7493
7494
7495static DECLCALLBACK(int) vmsvga3dBackIntraSurfaceCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7496{
7497 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7498
7499 RT_NOREF(pBackend, pDXContext);
7500 AssertFailed(); /** @todo Implement */
7501 return VERR_NOT_IMPLEMENTED;
7502}
7503
7504
7505static DECLCALLBACK(int) vmsvga3dBackDefineGBSurface_v3(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7506{
7507 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7508
7509 RT_NOREF(pBackend, pDXContext);
7510 AssertFailed(); /** @todo Implement */
7511 return VERR_NOT_IMPLEMENTED;
7512}
7513
7514
7515static DECLCALLBACK(int) vmsvga3dBackDXResolveCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7516{
7517 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7518
7519 RT_NOREF(pBackend, pDXContext);
7520 AssertFailed(); /** @todo Implement */
7521 return VERR_NOT_IMPLEMENTED;
7522}
7523
7524
7525static DECLCALLBACK(int) vmsvga3dBackDXPredResolveCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7526{
7527 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7528
7529 RT_NOREF(pBackend, pDXContext);
7530 AssertFailed(); /** @todo Implement */
7531 return VERR_NOT_IMPLEMENTED;
7532}
7533
7534
7535static DECLCALLBACK(int) vmsvga3dBackDXPredConvertRegion(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7536{
7537 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7538
7539 RT_NOREF(pBackend, pDXContext);
7540 AssertFailed(); /** @todo Implement */
7541 return VERR_NOT_IMPLEMENTED;
7542}
7543
7544
7545static DECLCALLBACK(int) vmsvga3dBackDXPredConvert(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7546{
7547 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7548
7549 RT_NOREF(pBackend, pDXContext);
7550 AssertFailed(); /** @todo Implement */
7551 return VERR_NOT_IMPLEMENTED;
7552}
7553
7554
7555static DECLCALLBACK(int) vmsvga3dBackWholeSurfaceCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7556{
7557 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7558
7559 RT_NOREF(pBackend, pDXContext);
7560 AssertFailed(); /** @todo Implement */
7561 return VERR_NOT_IMPLEMENTED;
7562}
7563
7564
7565static DECLCALLBACK(int) vmsvga3dBackDXDefineUAView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7566{
7567 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7568
7569 RT_NOREF(pBackend, pDXContext);
7570 AssertFailed(); /** @todo Implement */
7571 return VERR_NOT_IMPLEMENTED;
7572}
7573
7574
7575static DECLCALLBACK(int) vmsvga3dBackDXDestroyUAView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7576{
7577 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7578
7579 RT_NOREF(pBackend, pDXContext);
7580 AssertFailed(); /** @todo Implement */
7581 return VERR_NOT_IMPLEMENTED;
7582}
7583
7584
7585static DECLCALLBACK(int) vmsvga3dBackDXClearUAViewUint(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7586{
7587 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7588
7589 RT_NOREF(pBackend, pDXContext);
7590 AssertFailed(); /** @todo Implement */
7591 return VERR_NOT_IMPLEMENTED;
7592}
7593
7594
7595static DECLCALLBACK(int) vmsvga3dBackDXClearUAViewFloat(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7596{
7597 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7598
7599 RT_NOREF(pBackend, pDXContext);
7600 AssertFailed(); /** @todo Implement */
7601 return VERR_NOT_IMPLEMENTED;
7602}
7603
7604
7605static DECLCALLBACK(int) vmsvga3dBackDXCopyStructureCount(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7606{
7607 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7608
7609 RT_NOREF(pBackend, pDXContext);
7610 AssertFailed(); /** @todo Implement */
7611 return VERR_NOT_IMPLEMENTED;
7612}
7613
7614
7615static DECLCALLBACK(int) vmsvga3dBackDXSetUAViews(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7616{
7617 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7618
7619 RT_NOREF(pBackend, pDXContext);
7620 AssertFailed(); /** @todo Implement */
7621 return VERR_NOT_IMPLEMENTED;
7622}
7623
7624
7625static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexedInstancedIndirect(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7626{
7627 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7628
7629 RT_NOREF(pBackend, pDXContext);
7630 AssertFailed(); /** @todo Implement */
7631 return VERR_NOT_IMPLEMENTED;
7632}
7633
7634
7635static DECLCALLBACK(int) vmsvga3dBackDXDrawInstancedIndirect(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7636{
7637 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7638
7639 RT_NOREF(pBackend, pDXContext);
7640 AssertFailed(); /** @todo Implement */
7641 return VERR_NOT_IMPLEMENTED;
7642}
7643
7644
7645static DECLCALLBACK(int) vmsvga3dBackDXDispatch(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7646{
7647 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7648
7649 RT_NOREF(pBackend, pDXContext);
7650 AssertFailed(); /** @todo Implement */
7651 return VERR_NOT_IMPLEMENTED;
7652}
7653
7654
7655static DECLCALLBACK(int) vmsvga3dBackDXDispatchIndirect(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7656{
7657 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7658
7659 RT_NOREF(pBackend, pDXContext);
7660 AssertFailed(); /** @todo Implement */
7661 return VERR_NOT_IMPLEMENTED;
7662}
7663
7664
7665static DECLCALLBACK(int) vmsvga3dBackWriteZeroSurface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7666{
7667 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7668
7669 RT_NOREF(pBackend, pDXContext);
7670 AssertFailed(); /** @todo Implement */
7671 return VERR_NOT_IMPLEMENTED;
7672}
7673
7674
7675static DECLCALLBACK(int) vmsvga3dBackHintZeroSurface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7676{
7677 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7678
7679 RT_NOREF(pBackend, pDXContext);
7680 AssertFailed(); /** @todo Implement */
7681 return VERR_NOT_IMPLEMENTED;
7682}
7683
7684
7685static DECLCALLBACK(int) vmsvga3dBackDXTransferToBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7686{
7687 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7688
7689 RT_NOREF(pBackend, pDXContext);
7690 AssertFailed(); /** @todo Implement */
7691 return VERR_NOT_IMPLEMENTED;
7692}
7693
7694
7695static DECLCALLBACK(int) vmsvga3dBackDXSetStructureCount(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7696{
7697 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7698
7699 RT_NOREF(pBackend, pDXContext);
7700 AssertFailed(); /** @todo Implement */
7701 return VERR_NOT_IMPLEMENTED;
7702}
7703
7704
7705static DECLCALLBACK(int) vmsvga3dBackLogicOpsBitBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7706{
7707 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7708
7709 RT_NOREF(pBackend, pDXContext);
7710 AssertFailed(); /** @todo Implement */
7711 return VERR_NOT_IMPLEMENTED;
7712}
7713
7714
7715static DECLCALLBACK(int) vmsvga3dBackLogicOpsTransBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7716{
7717 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7718
7719 RT_NOREF(pBackend, pDXContext);
7720 AssertFailed(); /** @todo Implement */
7721 return VERR_NOT_IMPLEMENTED;
7722}
7723
7724
7725static DECLCALLBACK(int) vmsvga3dBackLogicOpsStretchBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7726{
7727 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7728
7729 RT_NOREF(pBackend, pDXContext);
7730 AssertFailed(); /** @todo Implement */
7731 return VERR_NOT_IMPLEMENTED;
7732}
7733
7734
7735static DECLCALLBACK(int) vmsvga3dBackLogicOpsColorFill(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7736{
7737 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7738
7739 RT_NOREF(pBackend, pDXContext);
7740 AssertFailed(); /** @todo Implement */
7741 return VERR_NOT_IMPLEMENTED;
7742}
7743
7744
7745static DECLCALLBACK(int) vmsvga3dBackLogicOpsAlphaBlend(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7746{
7747 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7748
7749 RT_NOREF(pBackend, pDXContext);
7750 AssertFailed(); /** @todo Implement */
7751 return VERR_NOT_IMPLEMENTED;
7752}
7753
7754
7755static DECLCALLBACK(int) vmsvga3dBackLogicOpsClearTypeBlend(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7756{
7757 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7758
7759 RT_NOREF(pBackend, pDXContext);
7760 AssertFailed(); /** @todo Implement */
7761 return VERR_NOT_IMPLEMENTED;
7762}
7763
7764
7765static DECLCALLBACK(int) vmsvga3dBackDefineGBSurface_v4(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7766{
7767 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7768
7769 RT_NOREF(pBackend, pDXContext);
7770 AssertFailed(); /** @todo Implement */
7771 return VERR_NOT_IMPLEMENTED;
7772}
7773
7774
7775static DECLCALLBACK(int) vmsvga3dBackDXSetCSUAViews(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7776{
7777 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7778
7779 RT_NOREF(pBackend, pDXContext);
7780 AssertFailed(); /** @todo Implement */
7781 return VERR_NOT_IMPLEMENTED;
7782}
7783
7784
7785static DECLCALLBACK(int) vmsvga3dBackDXSetMinLOD(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7786{
7787 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7788
7789 RT_NOREF(pBackend, pDXContext);
7790 AssertFailed(); /** @todo Implement */
7791 return VERR_NOT_IMPLEMENTED;
7792}
7793
7794
7795static DECLCALLBACK(int) vmsvga3dBackDXDefineStreamOutputWithMob(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7796{
7797 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7798
7799 RT_NOREF(pBackend, pDXContext);
7800 AssertFailed(); /** @todo Implement */
7801 return VERR_NOT_IMPLEMENTED;
7802}
7803
7804
7805static DECLCALLBACK(int) vmsvga3dBackDXSetShaderIface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7806{
7807 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7808
7809 RT_NOREF(pBackend, pDXContext);
7810 AssertFailed(); /** @todo Implement */
7811 return VERR_NOT_IMPLEMENTED;
7812}
7813
7814
7815static DECLCALLBACK(int) vmsvga3dBackDXBindStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7816{
7817 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7818
7819 RT_NOREF(pBackend, pDXContext);
7820 AssertFailed(); /** @todo Implement */
7821 return VERR_NOT_IMPLEMENTED;
7822}
7823
7824
7825static DECLCALLBACK(int) vmsvga3dBackSurfaceStretchBltNonMSToMS(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7826{
7827 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7828
7829 RT_NOREF(pBackend, pDXContext);
7830 AssertFailed(); /** @todo Implement */
7831 return VERR_NOT_IMPLEMENTED;
7832}
7833
7834
7835static DECLCALLBACK(int) vmsvga3dBackDXBindShaderIface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7836{
7837 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7838
7839 RT_NOREF(pBackend, pDXContext);
7840 AssertFailed(); /** @todo Implement */
7841 return VERR_NOT_IMPLEMENTED;
7842}
7843
7844
7845static DECLCALLBACK(int) vmsvga3dBackDXLoadState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PCPDMDEVHLPR3 pHlp, PSSMHANDLE pSSM)
7846{
7847 RT_NOREF(pThisCC);
7848 uint32_t u32;
7849 int rc;
7850
7851 rc = pHlp->pfnSSMGetU32(pSSM, &u32);
7852 AssertLogRelRCReturn(rc, rc);
7853 AssertLogRelRCReturn(u32 == pDXContext->pBackendDXContext->cShader, VERR_INVALID_STATE);
7854
7855 for (uint32_t i = 0; i < pDXContext->pBackendDXContext->cShader; ++i)
7856 {
7857 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[i];
7858
7859 rc = pHlp->pfnSSMGetU32(pSSM, &u32);
7860 AssertLogRelRCReturn(rc, rc);
7861 AssertLogRelReturn((SVGA3dShaderType)u32 == pDXShader->enmShaderType, VERR_INVALID_STATE);
7862
7863 if (pDXShader->enmShaderType == SVGA3D_SHADERTYPE_INVALID)
7864 continue;
7865
7866 pHlp->pfnSSMGetU32(pSSM, &pDXShader->soid);
7867
7868 pHlp->pfnSSMGetU32(pSSM, &u32);
7869 pDXShader->shaderInfo.enmProgramType = (VGPU10_PROGRAM_TYPE)u32;
7870
7871 rc = pHlp->pfnSSMGetU32(pSSM, &pDXShader->shaderInfo.cbBytecode);
7872 AssertLogRelRCReturn(rc, rc);
7873 AssertLogRelReturn(pDXShader->shaderInfo.cbBytecode <= 2 * SVGA3D_MAX_SHADER_MEMORY_BYTES, VERR_INVALID_STATE);
7874
7875 if (pDXShader->shaderInfo.cbBytecode)
7876 {
7877 pDXShader->shaderInfo.pvBytecode = RTMemAlloc(pDXShader->shaderInfo.cbBytecode);
7878 AssertPtrReturn(pDXShader->shaderInfo.pvBytecode, VERR_NO_MEMORY);
7879 pHlp->pfnSSMGetMem(pSSM, pDXShader->shaderInfo.pvBytecode, pDXShader->shaderInfo.cbBytecode);
7880 }
7881
7882 rc = pHlp->pfnSSMGetU32(pSSM, &pDXShader->shaderInfo.cInputSignature);
7883 AssertLogRelRCReturn(rc, rc);
7884 AssertLogRelReturn(pDXShader->shaderInfo.cInputSignature <= 32, VERR_INVALID_STATE);
7885 if (pDXShader->shaderInfo.cInputSignature)
7886 pHlp->pfnSSMGetMem(pSSM, pDXShader->shaderInfo.aInputSignature, pDXShader->shaderInfo.cInputSignature * sizeof(SVGA3dDXSignatureEntry));
7887
7888 rc = pHlp->pfnSSMGetU32(pSSM, &pDXShader->shaderInfo.cOutputSignature);
7889 AssertLogRelRCReturn(rc, rc);
7890 AssertLogRelReturn(pDXShader->shaderInfo.cOutputSignature <= 32, VERR_INVALID_STATE);
7891 if (pDXShader->shaderInfo.cOutputSignature)
7892 pHlp->pfnSSMGetMem(pSSM, pDXShader->shaderInfo.aOutputSignature, pDXShader->shaderInfo.cOutputSignature * sizeof(SVGA3dDXSignatureEntry));
7893
7894 rc = pHlp->pfnSSMGetU32(pSSM, &pDXShader->shaderInfo.cPatchConstantSignature);
7895 AssertLogRelRCReturn(rc, rc);
7896 AssertLogRelReturn(pDXShader->shaderInfo.cPatchConstantSignature <= 32, VERR_INVALID_STATE);
7897 if (pDXShader->shaderInfo.cPatchConstantSignature)
7898 pHlp->pfnSSMGetMem(pSSM, pDXShader->shaderInfo.aPatchConstantSignature, pDXShader->shaderInfo.cPatchConstantSignature * sizeof(SVGA3dDXSignatureEntry));
7899
7900 rc = pHlp->pfnSSMGetU32(pSSM, &pDXShader->shaderInfo.cDclResource);
7901 AssertLogRelRCReturn(rc, rc);
7902 AssertLogRelReturn(pDXShader->shaderInfo.cDclResource <= SVGA3D_DX_MAX_SRVIEWS, VERR_INVALID_STATE);
7903 if (pDXShader->shaderInfo.cDclResource)
7904 pHlp->pfnSSMGetMem(pSSM, pDXShader->shaderInfo.aOffDclResource, pDXShader->shaderInfo.cDclResource * sizeof(uint32_t));
7905 }
7906
7907 rc = pHlp->pfnSSMGetU32(pSSM, &pDXContext->pBackendDXContext->cSOTarget);
7908 AssertLogRelRCReturn(rc, rc);
7909
7910 return VINF_SUCCESS;
7911}
7912
7913
7914static DECLCALLBACK(int) vmsvga3dBackDXSaveState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PCPDMDEVHLPR3 pHlp, PSSMHANDLE pSSM)
7915{
7916 RT_NOREF(pThisCC);
7917 int rc;
7918
7919 pHlp->pfnSSMPutU32(pSSM, pDXContext->pBackendDXContext->cShader);
7920 for (uint32_t i = 0; i < pDXContext->pBackendDXContext->cShader; ++i)
7921 {
7922 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[i];
7923
7924 pHlp->pfnSSMPutU32(pSSM, (uint32_t)pDXShader->enmShaderType);
7925 if (pDXShader->enmShaderType == SVGA3D_SHADERTYPE_INVALID)
7926 continue;
7927
7928 pHlp->pfnSSMPutU32(pSSM, pDXShader->soid);
7929
7930 pHlp->pfnSSMPutU32(pSSM, (uint32_t)pDXShader->shaderInfo.enmProgramType);
7931
7932 pHlp->pfnSSMPutU32(pSSM, pDXShader->shaderInfo.cbBytecode);
7933 if (pDXShader->shaderInfo.cbBytecode)
7934 pHlp->pfnSSMPutMem(pSSM, pDXShader->shaderInfo.pvBytecode, pDXShader->shaderInfo.cbBytecode);
7935
7936 pHlp->pfnSSMPutU32(pSSM, pDXShader->shaderInfo.cInputSignature);
7937 if (pDXShader->shaderInfo.cInputSignature)
7938 pHlp->pfnSSMPutMem(pSSM, pDXShader->shaderInfo.aInputSignature, pDXShader->shaderInfo.cInputSignature * sizeof(SVGA3dDXSignatureEntry));
7939
7940 pHlp->pfnSSMPutU32(pSSM, pDXShader->shaderInfo.cOutputSignature);
7941 if (pDXShader->shaderInfo.cOutputSignature)
7942 pHlp->pfnSSMPutMem(pSSM, pDXShader->shaderInfo.aOutputSignature, pDXShader->shaderInfo.cOutputSignature * sizeof(SVGA3dDXSignatureEntry));
7943
7944 pHlp->pfnSSMPutU32(pSSM, pDXShader->shaderInfo.cPatchConstantSignature);
7945 if (pDXShader->shaderInfo.cPatchConstantSignature)
7946 pHlp->pfnSSMPutMem(pSSM, pDXShader->shaderInfo.aPatchConstantSignature, pDXShader->shaderInfo.cPatchConstantSignature * sizeof(SVGA3dDXSignatureEntry));
7947
7948 pHlp->pfnSSMPutU32(pSSM, pDXShader->shaderInfo.cDclResource);
7949 if (pDXShader->shaderInfo.cDclResource)
7950 pHlp->pfnSSMPutMem(pSSM, pDXShader->shaderInfo.aOffDclResource, pDXShader->shaderInfo.cDclResource * sizeof(uint32_t));
7951 }
7952 rc = pHlp->pfnSSMPutU32(pSSM, pDXContext->pBackendDXContext->cSOTarget);
7953 AssertLogRelRCReturn(rc, rc);
7954
7955 return VINF_SUCCESS;
7956}
7957
7958
7959static DECLCALLBACK(int) vmsvga3dBackQueryInterface(PVGASTATECC pThisCC, char const *pszInterfaceName, void *pvInterfaceFuncs, size_t cbInterfaceFuncs)
7960{
7961 RT_NOREF(pThisCC);
7962
7963 int rc = VINF_SUCCESS;
7964 if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_DX) == 0)
7965 {
7966 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSDX))
7967 {
7968 if (pvInterfaceFuncs)
7969 {
7970 VMSVGA3DBACKENDFUNCSDX *p = (VMSVGA3DBACKENDFUNCSDX *)pvInterfaceFuncs;
7971 p->pfnDXSaveState = vmsvga3dBackDXSaveState;
7972 p->pfnDXLoadState = vmsvga3dBackDXLoadState;
7973 p->pfnDXDefineContext = vmsvga3dBackDXDefineContext;
7974 p->pfnDXDestroyContext = vmsvga3dBackDXDestroyContext;
7975 p->pfnDXBindContext = vmsvga3dBackDXBindContext;
7976 p->pfnDXSwitchContext = vmsvga3dBackDXSwitchContext;
7977 p->pfnDXReadbackContext = vmsvga3dBackDXReadbackContext;
7978 p->pfnDXInvalidateContext = vmsvga3dBackDXInvalidateContext;
7979 p->pfnDXSetSingleConstantBuffer = vmsvga3dBackDXSetSingleConstantBuffer;
7980 p->pfnDXSetShaderResources = vmsvga3dBackDXSetShaderResources;
7981 p->pfnDXSetShader = vmsvga3dBackDXSetShader;
7982 p->pfnDXSetSamplers = vmsvga3dBackDXSetSamplers;
7983 p->pfnDXDraw = vmsvga3dBackDXDraw;
7984 p->pfnDXDrawIndexed = vmsvga3dBackDXDrawIndexed;
7985 p->pfnDXDrawInstanced = vmsvga3dBackDXDrawInstanced;
7986 p->pfnDXDrawIndexedInstanced = vmsvga3dBackDXDrawIndexedInstanced;
7987 p->pfnDXDrawAuto = vmsvga3dBackDXDrawAuto;
7988 p->pfnDXSetInputLayout = vmsvga3dBackDXSetInputLayout;
7989 p->pfnDXSetVertexBuffers = vmsvga3dBackDXSetVertexBuffers;
7990 p->pfnDXSetIndexBuffer = vmsvga3dBackDXSetIndexBuffer;
7991 p->pfnDXSetTopology = vmsvga3dBackDXSetTopology;
7992 p->pfnDXSetRenderTargets = vmsvga3dBackDXSetRenderTargets;
7993 p->pfnDXSetBlendState = vmsvga3dBackDXSetBlendState;
7994 p->pfnDXSetDepthStencilState = vmsvga3dBackDXSetDepthStencilState;
7995 p->pfnDXSetRasterizerState = vmsvga3dBackDXSetRasterizerState;
7996 p->pfnDXDefineQuery = vmsvga3dBackDXDefineQuery;
7997 p->pfnDXDestroyQuery = vmsvga3dBackDXDestroyQuery;
7998 p->pfnDXBindQuery = vmsvga3dBackDXBindQuery;
7999 p->pfnDXSetQueryOffset = vmsvga3dBackDXSetQueryOffset;
8000 p->pfnDXBeginQuery = vmsvga3dBackDXBeginQuery;
8001 p->pfnDXEndQuery = vmsvga3dBackDXEndQuery;
8002 p->pfnDXReadbackQuery = vmsvga3dBackDXReadbackQuery;
8003 p->pfnDXSetPredication = vmsvga3dBackDXSetPredication;
8004 p->pfnDXSetSOTargets = vmsvga3dBackDXSetSOTargets;
8005 p->pfnDXSetViewports = vmsvga3dBackDXSetViewports;
8006 p->pfnDXSetScissorRects = vmsvga3dBackDXSetScissorRects;
8007 p->pfnDXClearRenderTargetView = vmsvga3dBackDXClearRenderTargetView;
8008 p->pfnDXClearDepthStencilView = vmsvga3dBackDXClearDepthStencilView;
8009 p->pfnDXPredCopyRegion = vmsvga3dBackDXPredCopyRegion;
8010 p->pfnDXPredCopy = vmsvga3dBackDXPredCopy;
8011 p->pfnDXPresentBlt = vmsvga3dBackDXPresentBlt;
8012 p->pfnDXGenMips = vmsvga3dBackDXGenMips;
8013 p->pfnDXDefineShaderResourceView = vmsvga3dBackDXDefineShaderResourceView;
8014 p->pfnDXDestroyShaderResourceView = vmsvga3dBackDXDestroyShaderResourceView;
8015 p->pfnDXDefineRenderTargetView = vmsvga3dBackDXDefineRenderTargetView;
8016 p->pfnDXDestroyRenderTargetView = vmsvga3dBackDXDestroyRenderTargetView;
8017 p->pfnDXDefineDepthStencilView = vmsvga3dBackDXDefineDepthStencilView;
8018 p->pfnDXDestroyDepthStencilView = vmsvga3dBackDXDestroyDepthStencilView;
8019 p->pfnDXDefineElementLayout = vmsvga3dBackDXDefineElementLayout;
8020 p->pfnDXDestroyElementLayout = vmsvga3dBackDXDestroyElementLayout;
8021 p->pfnDXDefineBlendState = vmsvga3dBackDXDefineBlendState;
8022 p->pfnDXDestroyBlendState = vmsvga3dBackDXDestroyBlendState;
8023 p->pfnDXDefineDepthStencilState = vmsvga3dBackDXDefineDepthStencilState;
8024 p->pfnDXDestroyDepthStencilState = vmsvga3dBackDXDestroyDepthStencilState;
8025 p->pfnDXDefineRasterizerState = vmsvga3dBackDXDefineRasterizerState;
8026 p->pfnDXDestroyRasterizerState = vmsvga3dBackDXDestroyRasterizerState;
8027 p->pfnDXDefineSamplerState = vmsvga3dBackDXDefineSamplerState;
8028 p->pfnDXDestroySamplerState = vmsvga3dBackDXDestroySamplerState;
8029 p->pfnDXDefineShader = vmsvga3dBackDXDefineShader;
8030 p->pfnDXDestroyShader = vmsvga3dBackDXDestroyShader;
8031 p->pfnDXBindShader = vmsvga3dBackDXBindShader;
8032 p->pfnDXDefineStreamOutput = vmsvga3dBackDXDefineStreamOutput;
8033 p->pfnDXDestroyStreamOutput = vmsvga3dBackDXDestroyStreamOutput;
8034 p->pfnDXSetStreamOutput = vmsvga3dBackDXSetStreamOutput;
8035 p->pfnDXSetCOTable = vmsvga3dBackDXSetCOTable;
8036 p->pfnDXBufferCopy = vmsvga3dBackDXBufferCopy;
8037 p->pfnDXSurfaceCopyAndReadback = vmsvga3dBackDXSurfaceCopyAndReadback;
8038 p->pfnDXMoveQuery = vmsvga3dBackDXMoveQuery;
8039 p->pfnDXBindAllQuery = vmsvga3dBackDXBindAllQuery;
8040 p->pfnDXReadbackAllQuery = vmsvga3dBackDXReadbackAllQuery;
8041 p->pfnDXMobFence64 = vmsvga3dBackDXMobFence64;
8042 p->pfnDXBindAllShader = vmsvga3dBackDXBindAllShader;
8043 p->pfnDXHint = vmsvga3dBackDXHint;
8044 p->pfnDXBufferUpdate = vmsvga3dBackDXBufferUpdate;
8045 p->pfnDXSetVSConstantBufferOffset = vmsvga3dBackDXSetVSConstantBufferOffset;
8046 p->pfnDXSetPSConstantBufferOffset = vmsvga3dBackDXSetPSConstantBufferOffset;
8047 p->pfnDXSetGSConstantBufferOffset = vmsvga3dBackDXSetGSConstantBufferOffset;
8048 p->pfnDXSetHSConstantBufferOffset = vmsvga3dBackDXSetHSConstantBufferOffset;
8049 p->pfnDXSetDSConstantBufferOffset = vmsvga3dBackDXSetDSConstantBufferOffset;
8050 p->pfnDXSetCSConstantBufferOffset = vmsvga3dBackDXSetCSConstantBufferOffset;
8051 p->pfnDXCondBindAllShader = vmsvga3dBackDXCondBindAllShader;
8052 p->pfnScreenCopy = vmsvga3dBackScreenCopy;
8053 p->pfnGrowOTable = vmsvga3dBackGrowOTable;
8054 p->pfnDXGrowCOTable = vmsvga3dBackDXGrowCOTable;
8055 p->pfnIntraSurfaceCopy = vmsvga3dBackIntraSurfaceCopy;
8056 p->pfnDefineGBSurface_v3 = vmsvga3dBackDefineGBSurface_v3;
8057 p->pfnDXResolveCopy = vmsvga3dBackDXResolveCopy;
8058 p->pfnDXPredResolveCopy = vmsvga3dBackDXPredResolveCopy;
8059 p->pfnDXPredConvertRegion = vmsvga3dBackDXPredConvertRegion;
8060 p->pfnDXPredConvert = vmsvga3dBackDXPredConvert;
8061 p->pfnWholeSurfaceCopy = vmsvga3dBackWholeSurfaceCopy;
8062 p->pfnDXDefineUAView = vmsvga3dBackDXDefineUAView;
8063 p->pfnDXDestroyUAView = vmsvga3dBackDXDestroyUAView;
8064 p->pfnDXClearUAViewUint = vmsvga3dBackDXClearUAViewUint;
8065 p->pfnDXClearUAViewFloat = vmsvga3dBackDXClearUAViewFloat;
8066 p->pfnDXCopyStructureCount = vmsvga3dBackDXCopyStructureCount;
8067 p->pfnDXSetUAViews = vmsvga3dBackDXSetUAViews;
8068 p->pfnDXDrawIndexedInstancedIndirect = vmsvga3dBackDXDrawIndexedInstancedIndirect;
8069 p->pfnDXDrawInstancedIndirect = vmsvga3dBackDXDrawInstancedIndirect;
8070 p->pfnDXDispatch = vmsvga3dBackDXDispatch;
8071 p->pfnDXDispatchIndirect = vmsvga3dBackDXDispatchIndirect;
8072 p->pfnWriteZeroSurface = vmsvga3dBackWriteZeroSurface;
8073 p->pfnHintZeroSurface = vmsvga3dBackHintZeroSurface;
8074 p->pfnDXTransferToBuffer = vmsvga3dBackDXTransferToBuffer;
8075 p->pfnDXSetStructureCount = vmsvga3dBackDXSetStructureCount;
8076 p->pfnLogicOpsBitBlt = vmsvga3dBackLogicOpsBitBlt;
8077 p->pfnLogicOpsTransBlt = vmsvga3dBackLogicOpsTransBlt;
8078 p->pfnLogicOpsStretchBlt = vmsvga3dBackLogicOpsStretchBlt;
8079 p->pfnLogicOpsColorFill = vmsvga3dBackLogicOpsColorFill;
8080 p->pfnLogicOpsAlphaBlend = vmsvga3dBackLogicOpsAlphaBlend;
8081 p->pfnLogicOpsClearTypeBlend = vmsvga3dBackLogicOpsClearTypeBlend;
8082 p->pfnDefineGBSurface_v4 = vmsvga3dBackDefineGBSurface_v4;
8083 p->pfnDXSetCSUAViews = vmsvga3dBackDXSetCSUAViews;
8084 p->pfnDXSetMinLOD = vmsvga3dBackDXSetMinLOD;
8085 p->pfnDXDefineStreamOutputWithMob = vmsvga3dBackDXDefineStreamOutputWithMob;
8086 p->pfnDXSetShaderIface = vmsvga3dBackDXSetShaderIface;
8087 p->pfnDXBindStreamOutput = vmsvga3dBackDXBindStreamOutput;
8088 p->pfnSurfaceStretchBltNonMSToMS = vmsvga3dBackSurfaceStretchBltNonMSToMS;
8089 p->pfnDXBindShaderIface = vmsvga3dBackDXBindShaderIface;
8090 }
8091 }
8092 else
8093 {
8094 AssertFailed();
8095 rc = VERR_INVALID_PARAMETER;
8096 }
8097 }
8098 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_MAP) == 0)
8099 {
8100 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSMAP))
8101 {
8102 if (pvInterfaceFuncs)
8103 {
8104 VMSVGA3DBACKENDFUNCSMAP *p = (VMSVGA3DBACKENDFUNCSMAP *)pvInterfaceFuncs;
8105 p->pfnSurfaceMap = vmsvga3dBackSurfaceMap;
8106 p->pfnSurfaceUnmap = vmsvga3dBackSurfaceUnmap;
8107 }
8108 }
8109 else
8110 {
8111 AssertFailed();
8112 rc = VERR_INVALID_PARAMETER;
8113 }
8114 }
8115 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_GBO) == 0)
8116 {
8117 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSGBO))
8118 {
8119 if (pvInterfaceFuncs)
8120 {
8121 VMSVGA3DBACKENDFUNCSGBO *p = (VMSVGA3DBACKENDFUNCSGBO *)pvInterfaceFuncs;
8122 p->pfnScreenTargetBind = vmsvga3dScreenTargetBind;
8123 p->pfnScreenTargetUpdate = vmsvga3dScreenTargetUpdate;
8124 }
8125 }
8126 else
8127 {
8128 AssertFailed();
8129 rc = VERR_INVALID_PARAMETER;
8130 }
8131 }
8132 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_3D) == 0)
8133 {
8134 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCS3D))
8135 {
8136 if (pvInterfaceFuncs)
8137 {
8138 VMSVGA3DBACKENDFUNCS3D *p = (VMSVGA3DBACKENDFUNCS3D *)pvInterfaceFuncs;
8139 p->pfnInit = vmsvga3dBackInit;
8140 p->pfnPowerOn = vmsvga3dBackPowerOn;
8141 p->pfnTerminate = vmsvga3dBackTerminate;
8142 p->pfnReset = vmsvga3dBackReset;
8143 p->pfnQueryCaps = vmsvga3dBackQueryCaps;
8144 p->pfnChangeMode = vmsvga3dBackChangeMode;
8145 p->pfnCreateTexture = vmsvga3dBackCreateTexture;
8146 p->pfnSurfaceDestroy = vmsvga3dBackSurfaceDestroy;
8147 p->pfnSurfaceInvalidateImage = vmsvga3dBackSurfaceInvalidateImage;
8148 p->pfnSurfaceCopy = vmsvga3dBackSurfaceCopy;
8149 p->pfnSurfaceDMACopyBox = vmsvga3dBackSurfaceDMACopyBox;
8150 p->pfnSurfaceStretchBlt = vmsvga3dBackSurfaceStretchBlt;
8151 p->pfnUpdateHostScreenViewport = vmsvga3dBackUpdateHostScreenViewport;
8152 p->pfnDefineScreen = vmsvga3dBackDefineScreen;
8153 p->pfnDestroyScreen = vmsvga3dBackDestroyScreen;
8154 p->pfnSurfaceBlitToScreen = vmsvga3dBackSurfaceBlitToScreen;
8155 p->pfnSurfaceUpdateHeapBuffers = vmsvga3dBackSurfaceUpdateHeapBuffers;
8156 }
8157 }
8158 else
8159 {
8160 AssertFailed();
8161 rc = VERR_INVALID_PARAMETER;
8162 }
8163 }
8164 else
8165 rc = VERR_NOT_IMPLEMENTED;
8166 return rc;
8167}
8168
8169
8170extern VMSVGA3DBACKENDDESC const g_BackendDX =
8171{
8172 "DX",
8173 vmsvga3dBackQueryInterface
8174};
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