VirtualBox

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

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

Devices/Graphics: implemented queries; fixed generation of GS attributes: bugref:9830

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

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