VirtualBox

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

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

Devices/Graphics: texture arrays: bugref:9830

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