VirtualBox

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

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

Devices/Graphics: removed obsolete hack: bugref:9830

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