VirtualBox

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

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

Devices/Graphics: stream output; ClearView; typeless formats: bugref:9830

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette