VirtualBox

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

最後變更 在這個檔案從95016是 95016,由 vboxsync 提交於 3 年 前

Devices/Graphics: shader signatures: bugref:9830

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

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