VirtualBox

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

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

Devices/Graphics: a fix for piglit; map fix for compressed textures; remove obsolete assert: bugref:9830

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

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