VirtualBox

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

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

Devices/Graphics: cleanup: bugref:9830

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 328.1 KB
Line 
1/* $Id: DevVGA-SVGA3d-win-dx.cpp 94276 2022-03-16 18:21:51Z vboxsync $ */
2/** @file
3 * DevVMWare - VMWare SVGA device
4 */
5
6/*
7 * Copyright (C) 2020-2022 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DEV_VMSVGA
23#include <VBox/AssertGuest.h>
24#include <VBox/log.h>
25#include <VBox/vmm/pdmdev.h>
26#include <VBox/vmm/pgm.h>
27
28#include <iprt/assert.h>
29#include <iprt/avl.h>
30#include <iprt/errcore.h>
31#include <iprt/mem.h>
32
33#include <VBoxVideo.h> /* required by DevVGA.h */
34#include <VBoxVideo3D.h>
35
36/* should go BEFORE any other DevVGA include to make all DevVGA.h config defines be visible */
37#include "DevVGA.h"
38
39#include "DevVGA-SVGA.h"
40#include "DevVGA-SVGA3d.h"
41#include "DevVGA-SVGA3d-internal.h"
42#include "DevVGA-SVGA3d-dx-shader.h"
43
44/* d3d11_1.h has a structure field named 'Status' but Status is defined as int on Linux host */
45#if defined(Status)
46#undef Status
47#endif
48#include <d3d11_1.h>
49
50
51#ifdef RT_OS_WINDOWS
52# define VBOX_D3D11_LIBRARY_NAME "d3d11"
53#else
54# define VBOX_D3D11_LIBRARY_NAME "VBoxDxVk"
55#endif
56
57#define DX_FORCE_SINGLE_DEVICE
58
59/* This is not available on non Windows hosts. */
60#ifndef D3D_RELEASE
61# define D3D_RELEASE(a_Ptr) do { if ((a_Ptr)) (a_Ptr)->Release(); (a_Ptr) = NULL; } while (0)
62#endif
63
64/** Fake ID for the backend DX context. The context creates all shared textures. */
65#define DX_CID_BACKEND UINT32_C(0xfffffffe)
66
67#define DX_RELEASE_ARRAY(a_Count, a_papArray) do { \
68 for (uint32_t i = 0; i < (a_Count); ++i) \
69 D3D_RELEASE((a_papArray)[i]); \
70} while (0)
71
72typedef struct DXDEVICE
73{
74 ID3D11Device *pDevice; /* Device. */
75 ID3D11DeviceContext *pImmediateContext; /* Corresponding context. */
76 IDXGIFactory *pDxgiFactory; /* DXGI Factory. */
77 D3D_FEATURE_LEVEL FeatureLevel;
78
79 /* Staging buffer for transfer to surface buffers. */
80 ID3D11Buffer *pStagingBuffer; /* The staging buffer resource. */
81 uint32_t cbStagingBuffer; /* Current size of the staging buffer resource. */
82} DXDEVICE;
83
84/* Kind of a texture view. */
85typedef enum VMSVGA3DBACKVIEWTYPE
86{
87 VMSVGA3D_VIEWTYPE_NONE = 0,
88 VMSVGA3D_VIEWTYPE_RENDERTARGET = 1,
89 VMSVGA3D_VIEWTYPE_DEPTHSTENCIL = 2,
90 VMSVGA3D_VIEWTYPE_SHADERRESOURCE = 3
91} VMSVGA3DBACKVIEWTYPE;
92
93/* Information about a texture view to track all created views:.
94 * when a surface is invalidated, then all views must deleted;
95 * when a view is deleted, then the view must be unlinked from the surface.
96 */
97typedef struct DXVIEWINFO
98{
99 uint32_t sid; /* Surface which the view was created for. */
100 uint32_t cid; /* DX context which created the view. */
101 uint32_t viewId; /* View id assigned by the guest. */
102 VMSVGA3DBACKVIEWTYPE enmViewType;
103} DXVIEWINFO;
104
105/* Context Object Table element for a texture view. */
106typedef struct DXVIEW
107{
108 uint32_t cid; /* DX context which created the view. */
109 uint32_t sid; /* Surface which the view was created for. */
110 uint32_t viewId; /* View id assigned by the guest. */
111 VMSVGA3DBACKVIEWTYPE enmViewType;
112
113 union
114 {
115 ID3D11View *pView; /* The view object. */
116 ID3D11RenderTargetView *pRenderTargetView;
117 ID3D11DepthStencilView *pDepthStencilView;
118 ID3D11ShaderResourceView *pShaderResourceView;
119 } u;
120
121 RTLISTNODE nodeSurfaceView; /* Views are linked to the surface. */
122} DXVIEW;
123
124/* What kind of resource has been created for the VMSVGA3D surface. */
125typedef enum VMSVGA3DBACKRESTYPE
126{
127 VMSVGA3D_RESTYPE_NONE = 0,
128 VMSVGA3D_RESTYPE_SCREEN_TARGET = 1,
129 VMSVGA3D_RESTYPE_TEXTURE_1D = 2,
130 VMSVGA3D_RESTYPE_TEXTURE_2D = 3,
131 VMSVGA3D_RESTYPE_TEXTURE_CUBE = 4,
132 VMSVGA3D_RESTYPE_TEXTURE_3D = 5,
133 VMSVGA3D_RESTYPE_BUFFER = 6,
134} VMSVGA3DBACKRESTYPE;
135
136typedef struct VMSVGA3DBACKENDSURFACE
137{
138 VMSVGA3DBACKRESTYPE enmResType;
139 DXGI_FORMAT enmDxgiFormat;
140 union
141 {
142 ID3D11Resource *pResource;
143 ID3D11Texture1D *pTexture1D;
144 ID3D11Texture2D *pTexture2D;
145 ID3D11Texture3D *pTexture3D;
146 ID3D11Buffer *pBuffer;
147 } u;
148
149 /* 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 p->SemanticName = DXShaderGetOutputSemanticName(&pDXShader->shaderInfo, decl->registerIndex);
1708 p->SemanticIndex = decl->registerIndex;
1709 }
1710
1711 hr = pDevice->pDevice->CreateGeometryShaderWithStreamOutput(pDXShader->pvDXBC, pDXShader->cbDXBC,
1712 pDXStreamOutput->aDeclarationEntry, pDXStreamOutput->cDeclarationEntry,
1713 pEntry->numOutputStreamStrides ? pEntry->streamOutputStrideInBytes : NULL, pEntry->numOutputStreamStrides,
1714 pEntry->rasterizedStream,
1715 /*pClassLinkage=*/ NULL, &pDXShader->pGeometryShader);
1716 Assert(SUCCEEDED(hr));
1717 if (SUCCEEDED(hr))
1718 pDXShader->soid = soid;
1719 }
1720 break;
1721 }
1722 case SVGA3D_SHADERTYPE_HS:
1723 case SVGA3D_SHADERTYPE_DS:
1724 case SVGA3D_SHADERTYPE_CS:
1725 default:
1726 ASSERT_GUEST_FAILED_RETURN(E_INVALIDARG);
1727 }
1728
1729 return hr;
1730}
1731
1732
1733static void dxShaderSet(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderType type, DXSHADER *pDXShader)
1734{
1735 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
1736
1737 switch (type)
1738 {
1739 case SVGA3D_SHADERTYPE_VS:
1740 pDevice->pImmediateContext->VSSetShader(pDXShader ? pDXShader->pVertexShader : NULL, NULL, 0);
1741 break;
1742 case SVGA3D_SHADERTYPE_PS:
1743 pDevice->pImmediateContext->PSSetShader(pDXShader ? pDXShader->pPixelShader : NULL, NULL, 0);
1744 break;
1745 case SVGA3D_SHADERTYPE_GS:
1746 {
1747 Assert(!pDXShader || (pDXShader->soid == pDXContext->svgaDXContext.streamOut.soid));
1748 pDevice->pImmediateContext->GSSetShader(pDXShader ? pDXShader->pGeometryShader : NULL, NULL, 0);
1749 } break;
1750 case SVGA3D_SHADERTYPE_HS:
1751 case SVGA3D_SHADERTYPE_DS:
1752 case SVGA3D_SHADERTYPE_CS:
1753 default:
1754 ASSERT_GUEST_FAILED_RETURN_VOID();
1755 }
1756}
1757
1758
1759static void dxConstantBufferSet(DXDEVICE *pDevice, uint32_t slot, SVGA3dShaderType type, ID3D11Buffer *pConstantBuffer)
1760{
1761 switch (type)
1762 {
1763 case SVGA3D_SHADERTYPE_VS:
1764 pDevice->pImmediateContext->VSSetConstantBuffers(slot, 1, &pConstantBuffer);
1765 break;
1766 case SVGA3D_SHADERTYPE_PS:
1767 pDevice->pImmediateContext->PSSetConstantBuffers(slot, 1, &pConstantBuffer);
1768 break;
1769 case SVGA3D_SHADERTYPE_GS:
1770 pDevice->pImmediateContext->GSSetConstantBuffers(slot, 1, &pConstantBuffer);
1771 break;
1772 case SVGA3D_SHADERTYPE_HS:
1773 case SVGA3D_SHADERTYPE_DS:
1774 case SVGA3D_SHADERTYPE_CS:
1775 default:
1776 ASSERT_GUEST_FAILED_RETURN_VOID();
1777 }
1778}
1779
1780
1781static void dxSamplerSet(DXDEVICE *pDevice, SVGA3dShaderType type, uint32_t startSampler, uint32_t cSampler, ID3D11SamplerState * const *papSampler)
1782{
1783 switch (type)
1784 {
1785 case SVGA3D_SHADERTYPE_VS:
1786 pDevice->pImmediateContext->VSSetSamplers(startSampler, cSampler, papSampler);
1787 break;
1788 case SVGA3D_SHADERTYPE_PS:
1789 pDevice->pImmediateContext->PSSetSamplers(startSampler, cSampler, papSampler);
1790 break;
1791 case SVGA3D_SHADERTYPE_GS:
1792 pDevice->pImmediateContext->GSSetSamplers(startSampler, cSampler, papSampler);
1793 break;
1794 case SVGA3D_SHADERTYPE_HS:
1795 case SVGA3D_SHADERTYPE_DS:
1796 case SVGA3D_SHADERTYPE_CS:
1797 default:
1798 ASSERT_GUEST_FAILED_RETURN_VOID();
1799 }
1800}
1801
1802
1803static void dxShaderResourceViewSet(DXDEVICE *pDevice, SVGA3dShaderType type, uint32_t startView, uint32_t cShaderResourceView, ID3D11ShaderResourceView * const *papShaderResourceView)
1804{
1805 switch (type)
1806 {
1807 case SVGA3D_SHADERTYPE_VS:
1808 pDevice->pImmediateContext->VSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
1809 break;
1810 case SVGA3D_SHADERTYPE_PS:
1811 pDevice->pImmediateContext->PSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
1812 break;
1813 case SVGA3D_SHADERTYPE_GS:
1814 pDevice->pImmediateContext->GSSetShaderResources(startView, cShaderResourceView, papShaderResourceView);
1815 break;
1816 case SVGA3D_SHADERTYPE_HS:
1817 case SVGA3D_SHADERTYPE_DS:
1818 case SVGA3D_SHADERTYPE_CS:
1819 default:
1820 ASSERT_GUEST_FAILED_RETURN_VOID();
1821 }
1822}
1823
1824
1825static int dxBackendSurfaceAlloc(PVMSVGA3DBACKENDSURFACE *ppBackendSurface)
1826{
1827 PVMSVGA3DBACKENDSURFACE pBackendSurface = (PVMSVGA3DBACKENDSURFACE)RTMemAllocZ(sizeof(VMSVGA3DBACKENDSURFACE));
1828 AssertPtrReturn(pBackendSurface, VERR_NO_MEMORY);
1829 pBackendSurface->cidDrawing = SVGA_ID_INVALID;
1830 RTListInit(&pBackendSurface->u2.Texture.listView);
1831 *ppBackendSurface = pBackendSurface;
1832 return VINF_SUCCESS;
1833}
1834
1835
1836static HRESULT dxInitSharedHandle(PVMSVGA3DBACKEND pBackend, PVMSVGA3DBACKENDSURFACE pBackendSurface)
1837{
1838 if (pBackend->fSingleDevice)
1839 return S_OK;
1840
1841 /* Get the shared handle. */
1842 IDXGIResource *pDxgiResource = NULL;
1843 HRESULT hr = pBackendSurface->u.pResource->QueryInterface(__uuidof(IDXGIResource), (void**)&pDxgiResource);
1844 Assert(SUCCEEDED(hr));
1845 if (SUCCEEDED(hr))
1846 {
1847 hr = pDxgiResource->GetSharedHandle(&pBackendSurface->SharedHandle);
1848 Assert(SUCCEEDED(hr));
1849 D3D_RELEASE(pDxgiResource);
1850 }
1851
1852 return hr;
1853}
1854
1855
1856static int vmsvga3dBackSurfaceCreateScreenTarget(PVGASTATECC pThisCC, PVMSVGA3DSURFACE pSurface)
1857{
1858 PVMSVGA3DSTATE p3dState = pThisCC->svga.p3dState;
1859 AssertReturn(p3dState, VERR_INVALID_STATE);
1860
1861 PVMSVGA3DBACKEND pBackend = p3dState->pBackend;
1862 AssertReturn(pBackend, VERR_INVALID_STATE);
1863
1864 DXDEVICE *pDXDevice = &pBackend->dxDevice;
1865 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
1866
1867 /* Surface must have SCREEN_TARGET flag. */
1868 ASSERT_GUEST_RETURN(RT_BOOL(pSurface->surfaceFlags & SVGA3D_SURFACE_SCREENTARGET), VERR_INVALID_PARAMETER);
1869
1870 if (VMSVGA3DSURFACE_HAS_HW_SURFACE(pSurface))
1871 {
1872 AssertFailed(); /* Should the function not be used like that? */
1873 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
1874 }
1875
1876 PVMSVGA3DBACKENDSURFACE pBackendSurface;
1877 int rc = dxBackendSurfaceAlloc(&pBackendSurface);
1878 AssertRCReturn(rc, rc);
1879
1880 D3D11_TEXTURE2D_DESC td;
1881 RT_ZERO(td);
1882 td.Width = pSurface->paMipmapLevels[0].mipmapSize.width;
1883 td.Height = pSurface->paMipmapLevels[0].mipmapSize.height;
1884 Assert(pSurface->cLevels == 1);
1885 td.MipLevels = 1;
1886 td.ArraySize = 1;
1887 td.Format = vmsvgaDXSurfaceFormat2Dxgi(pSurface->format);
1888 td.SampleDesc.Count = 1;
1889 td.SampleDesc.Quality = 0;
1890 td.Usage = D3D11_USAGE_DEFAULT;
1891 td.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
1892 td.CPUAccessFlags = 0;
1893 td.MiscFlags = pBackend->fSingleDevice ? 0 : D3D11_RESOURCE_MISC_SHARED;
1894
1895 HRESULT hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->u.pTexture2D);
1896 Assert(SUCCEEDED(hr));
1897 if (SUCCEEDED(hr))
1898 {
1899 /* Map-able texture. */
1900 td.Usage = D3D11_USAGE_DYNAMIC;
1901 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
1902 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
1903 td.MiscFlags = 0;
1904 hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->dynamic.pTexture2D);
1905 Assert(SUCCEEDED(hr));
1906 }
1907
1908 if (SUCCEEDED(hr))
1909 {
1910 /* Staging texture. */
1911 td.Usage = D3D11_USAGE_STAGING;
1912 td.BindFlags = 0; /* No flags allowed. */
1913 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
1914 hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &pBackendSurface->staging.pTexture2D);
1915 Assert(SUCCEEDED(hr));
1916 }
1917
1918 if (SUCCEEDED(hr))
1919 hr = dxInitSharedHandle(pBackend, pBackendSurface);
1920
1921 if (SUCCEEDED(hr))
1922 {
1923 /*
1924 * Success.
1925 */
1926 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_SCREEN_TARGET;
1927 pBackendSurface->enmDxgiFormat = td.Format;
1928 pSurface->pBackendSurface = pBackendSurface;
1929 pSurface->idAssociatedContext = DX_CID_BACKEND;
1930 return VINF_SUCCESS;
1931 }
1932
1933 /* Failure. */
1934 D3D_RELEASE(pBackendSurface->staging.pTexture2D);
1935 D3D_RELEASE(pBackendSurface->dynamic.pTexture2D);
1936 D3D_RELEASE(pBackendSurface->u.pTexture2D);
1937 RTMemFree(pBackendSurface);
1938 return VERR_NO_MEMORY;
1939}
1940
1941
1942static UINT dxBindFlags(SVGA3dSurfaceAllFlags surfaceFlags)
1943{
1944 /* Catch unimplemented flags. */
1945 Assert(!RT_BOOL(surfaceFlags & (SVGA3D_SURFACE_BIND_LOGICOPS | SVGA3D_SURFACE_BIND_RAW_VIEWS)));
1946
1947 UINT BindFlags = 0;
1948
1949 if (surfaceFlags & SVGA3D_SURFACE_BIND_VERTEX_BUFFER) BindFlags |= D3D11_BIND_VERTEX_BUFFER;
1950 if (surfaceFlags & SVGA3D_SURFACE_BIND_INDEX_BUFFER) BindFlags |= D3D11_BIND_INDEX_BUFFER;
1951 if (surfaceFlags & SVGA3D_SURFACE_BIND_CONSTANT_BUFFER) BindFlags |= D3D11_BIND_CONSTANT_BUFFER;
1952 if (surfaceFlags & SVGA3D_SURFACE_BIND_SHADER_RESOURCE) BindFlags |= D3D11_BIND_SHADER_RESOURCE;
1953 if (surfaceFlags & SVGA3D_SURFACE_BIND_RENDER_TARGET) BindFlags |= D3D11_BIND_RENDER_TARGET;
1954 if (surfaceFlags & SVGA3D_SURFACE_BIND_DEPTH_STENCIL) BindFlags |= D3D11_BIND_DEPTH_STENCIL;
1955 if (surfaceFlags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT) BindFlags |= D3D11_BIND_STREAM_OUTPUT;
1956 if (surfaceFlags & SVGA3D_SURFACE_BIND_UAVIEW) BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
1957
1958 return BindFlags;
1959}
1960
1961
1962static DXDEVICE *dxSurfaceDevice(PVMSVGA3DSTATE p3dState, PVMSVGA3DSURFACE pSurface, PVMSVGA3DDXCONTEXT pDXContext, UINT *pMiscFlags)
1963{
1964 if (p3dState->pBackend->fSingleDevice)
1965 {
1966 *pMiscFlags = 0;
1967 return &p3dState->pBackend->dxDevice;
1968 }
1969
1970 if (dxIsSurfaceShareable(pSurface))
1971 {
1972 *pMiscFlags = D3D11_RESOURCE_MISC_SHARED;
1973 return &p3dState->pBackend->dxDevice;
1974 }
1975
1976 *pMiscFlags = 0;
1977 return &pDXContext->pBackendDXContext->dxDevice;
1978}
1979
1980static int vmsvga3dBackSurfaceCreateTexture(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
1981{
1982 PVMSVGA3DSTATE p3dState = pThisCC->svga.p3dState;
1983 AssertReturn(p3dState, VERR_INVALID_STATE);
1984
1985 PVMSVGA3DBACKEND pBackend = p3dState->pBackend;
1986 AssertReturn(pBackend, VERR_INVALID_STATE);
1987
1988 UINT MiscFlags;
1989 DXDEVICE *pDXDevice = dxSurfaceDevice(p3dState, pSurface, pDXContext, &MiscFlags);
1990 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
1991
1992 if (pSurface->pBackendSurface != NULL)
1993 {
1994 AssertFailed(); /** @todo Should the function not be used like that? */
1995 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
1996 }
1997
1998 PVMSVGA3DBACKENDSURFACE pBackendSurface;
1999 int rc = dxBackendSurfaceAlloc(&pBackendSurface);
2000 AssertRCReturn(rc, rc);
2001
2002 uint32_t const cWidth = pSurface->paMipmapLevels[0].mipmapSize.width;
2003 uint32_t const cHeight = pSurface->paMipmapLevels[0].mipmapSize.height;
2004 uint32_t const cDepth = pSurface->paMipmapLevels[0].mipmapSize.depth;
2005 uint32_t const numMipLevels = pSurface->cLevels;
2006
2007 DXGI_FORMAT dxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(pSurface->format);
2008 AssertReturn(dxgiFormat != DXGI_FORMAT_UNKNOWN, E_FAIL);
2009
2010 /*
2011 * Create D3D11 texture object.
2012 */
2013 D3D11_SUBRESOURCE_DATA *paInitialData = NULL;
2014 if (pSurface->paMipmapLevels[0].pSurfaceData)
2015 {
2016 /* Can happen for a non GBO surface or if GBO texture was updated prior to creation of the hardware resource. */
2017 uint32_t const cSubresource = numMipLevels * pSurface->surfaceDesc.numArrayElements;
2018 paInitialData = (D3D11_SUBRESOURCE_DATA *)RTMemAlloc(cSubresource * sizeof(D3D11_SUBRESOURCE_DATA));
2019 AssertPtrReturn(paInitialData, VERR_NO_MEMORY);
2020
2021 for (uint32_t i = 0; i < cSubresource; ++i)
2022 {
2023 PVMSVGA3DMIPMAPLEVEL pMipmapLevel = &pSurface->paMipmapLevels[i];
2024 D3D11_SUBRESOURCE_DATA *p = &paInitialData[i];
2025 p->pSysMem = pMipmapLevel->pSurfaceData;
2026 p->SysMemPitch = pMipmapLevel->cbSurfacePitch;
2027 p->SysMemSlicePitch = pMipmapLevel->cbSurfacePlane;
2028 }
2029 }
2030
2031 HRESULT hr = S_OK;
2032 if (pSurface->surfaceFlags & SVGA3D_SURFACE_SCREENTARGET)
2033 {
2034 /*
2035 * Create the texture in backend device and open for the specified context.
2036 */
2037 D3D11_TEXTURE2D_DESC td;
2038 RT_ZERO(td);
2039 td.Width = pSurface->paMipmapLevels[0].mipmapSize.width;
2040 td.Height = pSurface->paMipmapLevels[0].mipmapSize.height;
2041 Assert(pSurface->cLevels == 1);
2042 td.MipLevels = 1;
2043 td.ArraySize = 1;
2044 td.Format = dxgiFormat;
2045 td.SampleDesc.Count = 1;
2046 td.SampleDesc.Quality = 0;
2047 td.Usage = D3D11_USAGE_DEFAULT;
2048 td.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
2049 td.CPUAccessFlags = 0;
2050 td.MiscFlags = MiscFlags;
2051
2052 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->u.pTexture2D);
2053 Assert(SUCCEEDED(hr));
2054 if (SUCCEEDED(hr))
2055 {
2056 /* Map-able texture. */
2057 td.Usage = D3D11_USAGE_DYNAMIC;
2058 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2059 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2060 td.MiscFlags = 0;
2061 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->dynamic.pTexture2D);
2062 Assert(SUCCEEDED(hr));
2063 }
2064
2065 if (SUCCEEDED(hr))
2066 {
2067 /* Staging texture. */
2068 td.Usage = D3D11_USAGE_STAGING;
2069 td.BindFlags = 0; /* No flags allowed. */
2070 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2071 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->staging.pTexture2D);
2072 Assert(SUCCEEDED(hr));
2073 }
2074
2075 if (SUCCEEDED(hr))
2076 hr = dxInitSharedHandle(pBackend, pBackendSurface);
2077
2078 if (SUCCEEDED(hr))
2079 {
2080 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_SCREEN_TARGET;
2081 }
2082 }
2083 else if (pSurface->surfaceFlags & SVGA3D_SURFACE_CUBEMAP)
2084 {
2085 Assert(pSurface->cFaces == 6);
2086 Assert(cWidth == cHeight);
2087 Assert(cDepth == 1);
2088//DEBUG_BREAKPOINT_TEST();
2089
2090 D3D11_TEXTURE2D_DESC td;
2091 RT_ZERO(td);
2092 td.Width = cWidth;
2093 td.Height = cHeight;
2094 td.MipLevels = numMipLevels;
2095 td.ArraySize = pSurface->surfaceDesc.numArrayElements; /* This is 6 * numCubes */
2096 td.Format = dxgiFormat;
2097 td.SampleDesc.Count = 1;
2098 td.SampleDesc.Quality = 0;
2099 td.Usage = D3D11_USAGE_DEFAULT;
2100 td.BindFlags = dxBindFlags(pSurface->surfaceFlags);
2101 td.CPUAccessFlags = 0; /** @todo */
2102 td.MiscFlags = MiscFlags | D3D11_RESOURCE_MISC_TEXTURECUBE; /** @todo */
2103 if ( numMipLevels > 1
2104 && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
2105 td.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
2106
2107 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->u.pTexture2D);
2108 Assert(SUCCEEDED(hr));
2109 if (SUCCEEDED(hr))
2110 {
2111 /* Map-able texture. */
2112 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2113 td.ArraySize = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2114 td.Usage = D3D11_USAGE_DYNAMIC;
2115 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2116 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2117 td.MiscFlags = 0;
2118 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->dynamic.pTexture2D);
2119 Assert(SUCCEEDED(hr));
2120 }
2121
2122 if (SUCCEEDED(hr))
2123 {
2124 /* Staging texture. */
2125 td.Usage = D3D11_USAGE_STAGING;
2126 td.BindFlags = 0; /* No flags allowed. */
2127 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2128 td.MiscFlags = 0;
2129 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->staging.pTexture2D);
2130 Assert(SUCCEEDED(hr));
2131 }
2132
2133 if (SUCCEEDED(hr))
2134 hr = dxInitSharedHandle(pBackend, pBackendSurface);
2135
2136 if (SUCCEEDED(hr))
2137 {
2138 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE_CUBE;
2139 }
2140 }
2141 else if (pSurface->surfaceFlags & SVGA3D_SURFACE_1D)
2142 {
2143 /*
2144 * 1D texture.
2145 */
2146 Assert(pSurface->cFaces == 1);
2147
2148 D3D11_TEXTURE1D_DESC td;
2149 RT_ZERO(td);
2150 td.Width = cWidth;
2151 td.MipLevels = numMipLevels;
2152 td.ArraySize = pSurface->surfaceDesc.numArrayElements;
2153 td.Format = dxgiFormat;
2154 td.Usage = D3D11_USAGE_DEFAULT;
2155 td.BindFlags = dxBindFlags(pSurface->surfaceFlags);
2156 td.CPUAccessFlags = 0;
2157 td.MiscFlags = MiscFlags; /** @todo */
2158 if ( numMipLevels > 1
2159 && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
2160 td.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
2161
2162 hr = pDXDevice->pDevice->CreateTexture1D(&td, paInitialData, &pBackendSurface->u.pTexture1D);
2163 Assert(SUCCEEDED(hr));
2164 if (SUCCEEDED(hr))
2165 {
2166 /* Map-able texture. */
2167 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2168 td.ArraySize = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2169 td.Usage = D3D11_USAGE_DYNAMIC;
2170 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2171 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2172 td.MiscFlags = 0;
2173 hr = pDXDevice->pDevice->CreateTexture1D(&td, paInitialData, &pBackendSurface->dynamic.pTexture1D);
2174 Assert(SUCCEEDED(hr));
2175 }
2176
2177 if (SUCCEEDED(hr))
2178 {
2179 /* Staging texture. */
2180 td.Usage = D3D11_USAGE_STAGING;
2181 td.BindFlags = 0; /* No flags allowed. */
2182 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2183 td.MiscFlags = 0;
2184 hr = pDXDevice->pDevice->CreateTexture1D(&td, paInitialData, &pBackendSurface->staging.pTexture1D);
2185 Assert(SUCCEEDED(hr));
2186 }
2187
2188 if (SUCCEEDED(hr))
2189 hr = dxInitSharedHandle(pBackend, pBackendSurface);
2190
2191 if (SUCCEEDED(hr))
2192 {
2193 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE_1D;
2194 }
2195 }
2196 else
2197 {
2198 if (pSurface->surfaceFlags & SVGA3D_SURFACE_VOLUME)
2199 {
2200 /*
2201 * Volume texture.
2202 */
2203 Assert(pSurface->cFaces == 1);
2204 Assert(pSurface->surfaceDesc.numArrayElements == 1);
2205
2206 D3D11_TEXTURE3D_DESC td;
2207 RT_ZERO(td);
2208 td.Width = cWidth;
2209 td.Height = cHeight;
2210 td.Depth = cDepth;
2211 td.MipLevels = numMipLevels;
2212 td.Format = dxgiFormat;
2213 td.Usage = D3D11_USAGE_DEFAULT;
2214 td.BindFlags = dxBindFlags(pSurface->surfaceFlags);
2215 td.CPUAccessFlags = 0; /** @todo */
2216 td.MiscFlags = MiscFlags; /** @todo */
2217 if ( numMipLevels > 1
2218 && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
2219 td.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
2220
2221 hr = pDXDevice->pDevice->CreateTexture3D(&td, paInitialData, &pBackendSurface->u.pTexture3D);
2222 Assert(SUCCEEDED(hr));
2223 if (SUCCEEDED(hr))
2224 {
2225 /* Map-able texture. */
2226 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2227 td.Usage = D3D11_USAGE_DYNAMIC;
2228 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2229 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2230 td.MiscFlags = 0;
2231 hr = pDXDevice->pDevice->CreateTexture3D(&td, paInitialData, &pBackendSurface->dynamic.pTexture3D);
2232 Assert(SUCCEEDED(hr));
2233 }
2234
2235 if (SUCCEEDED(hr))
2236 {
2237 /* Staging texture. */
2238 td.Usage = D3D11_USAGE_STAGING;
2239 td.BindFlags = 0; /* No flags allowed. */
2240 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2241 td.MiscFlags = 0;
2242 hr = pDXDevice->pDevice->CreateTexture3D(&td, paInitialData, &pBackendSurface->staging.pTexture3D);
2243 Assert(SUCCEEDED(hr));
2244 }
2245
2246 if (SUCCEEDED(hr))
2247 hr = dxInitSharedHandle(pBackend, pBackendSurface);
2248
2249 if (SUCCEEDED(hr))
2250 {
2251 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE_3D;
2252 }
2253 }
2254 else
2255 {
2256 /*
2257 * 2D texture.
2258 */
2259 Assert(cDepth == 1);
2260 Assert(pSurface->cFaces == 1);
2261
2262 D3D11_TEXTURE2D_DESC td;
2263 RT_ZERO(td);
2264 td.Width = cWidth;
2265 td.Height = cHeight;
2266 td.MipLevels = numMipLevels;
2267 td.ArraySize = pSurface->surfaceDesc.numArrayElements;
2268 td.Format = dxgiFormat;
2269 td.SampleDesc.Count = 1;
2270 td.SampleDesc.Quality = 0;
2271 td.Usage = D3D11_USAGE_DEFAULT;
2272 td.BindFlags = dxBindFlags(pSurface->surfaceFlags);
2273 td.CPUAccessFlags = 0; /** @todo */
2274 td.MiscFlags = MiscFlags; /** @todo */
2275 if ( numMipLevels > 1
2276 && (td.BindFlags & (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET)) == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET))
2277 td.MiscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS; /* Required for GenMips. */
2278
2279 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->u.pTexture2D);
2280 Assert(SUCCEEDED(hr));
2281 if (SUCCEEDED(hr))
2282 {
2283 /* Map-able texture. */
2284 td.MipLevels = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2285 td.ArraySize = 1; /* Must be for D3D11_USAGE_DYNAMIC. */
2286 td.Usage = D3D11_USAGE_DYNAMIC;
2287 td.BindFlags = D3D11_BIND_SHADER_RESOURCE; /* Have to specify a supported flag, otherwise E_INVALIDARG will be returned. */
2288 td.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2289 td.MiscFlags = 0;
2290 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->dynamic.pTexture2D);
2291 Assert(SUCCEEDED(hr));
2292 }
2293
2294 if (SUCCEEDED(hr))
2295 {
2296 /* Staging texture. */
2297 td.Usage = D3D11_USAGE_STAGING;
2298 td.BindFlags = 0; /* No flags allowed. */
2299 td.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
2300 td.MiscFlags = 0;
2301 hr = pDXDevice->pDevice->CreateTexture2D(&td, paInitialData, &pBackendSurface->staging.pTexture2D);
2302 Assert(SUCCEEDED(hr));
2303 }
2304
2305 if (SUCCEEDED(hr))
2306 hr = dxInitSharedHandle(pBackend, pBackendSurface);
2307
2308 if (SUCCEEDED(hr))
2309 {
2310 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_TEXTURE_2D;
2311 }
2312 }
2313 }
2314
2315 Assert(hr == S_OK);
2316
2317 RTMemFree(paInitialData);
2318
2319 if (pSurface->autogenFilter != SVGA3D_TEX_FILTER_NONE)
2320 {
2321 }
2322
2323 if (SUCCEEDED(hr))
2324 {
2325 /*
2326 * Success.
2327 */
2328 LogFunc(("sid = %u\n", pSurface->id));
2329 pBackendSurface->enmDxgiFormat = dxgiFormat;
2330 pSurface->pBackendSurface = pBackendSurface;
2331 if (p3dState->pBackend->fSingleDevice || RT_BOOL(MiscFlags & D3D11_RESOURCE_MISC_SHARED))
2332 pSurface->idAssociatedContext = DX_CID_BACKEND;
2333 else
2334 pSurface->idAssociatedContext = pDXContext->cid;
2335 return VINF_SUCCESS;
2336 }
2337
2338 D3D_RELEASE(pBackendSurface->staging.pResource);
2339 D3D_RELEASE(pBackendSurface->dynamic.pResource);
2340 D3D_RELEASE(pBackendSurface->u.pResource);
2341 RTMemFree(pBackendSurface);
2342 return VERR_NO_MEMORY;
2343}
2344
2345
2346static int vmsvga3dBackSurfaceCreateBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
2347{
2348 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
2349 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
2350
2351 /* Buffers should be created as such. */
2352 AssertReturn(RT_BOOL(pSurface->surfaceFlags & ( SVGA3D_SURFACE_HINT_INDEXBUFFER
2353 | SVGA3D_SURFACE_HINT_VERTEXBUFFER
2354 | SVGA3D_SURFACE_BIND_VERTEX_BUFFER
2355 | SVGA3D_SURFACE_BIND_INDEX_BUFFER
2356 )), VERR_INVALID_PARAMETER);
2357
2358 if (pSurface->pBackendSurface != NULL)
2359 {
2360 AssertFailed(); /** @todo Should the function not be used like that? */
2361 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
2362 }
2363
2364 PVMSVGA3DMIPMAPLEVEL pMipLevel;
2365 int rc = vmsvga3dMipmapLevel(pSurface, 0, 0, &pMipLevel);
2366 AssertRCReturn(rc, rc);
2367
2368 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2369 rc = dxBackendSurfaceAlloc(&pBackendSurface);
2370 AssertRCReturn(rc, rc);
2371
2372 LogFunc(("sid = %u, size = %u\n", pSurface->id, pMipLevel->cbSurface));
2373
2374 /* Upload the current data, if any. */
2375 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
2376 D3D11_SUBRESOURCE_DATA initialData;
2377 if (pMipLevel->pSurfaceData)
2378 {
2379 initialData.pSysMem = pMipLevel->pSurfaceData;
2380 initialData.SysMemPitch = pMipLevel->cbSurface;
2381 initialData.SysMemSlicePitch = pMipLevel->cbSurface;
2382
2383 pInitialData = &initialData;
2384 }
2385
2386 D3D11_BUFFER_DESC bd;
2387 RT_ZERO(bd);
2388 bd.ByteWidth = pMipLevel->cbSurface;
2389 bd.Usage = D3D11_USAGE_DEFAULT;
2390 bd.BindFlags = D3D11_BIND_VERTEX_BUFFER
2391 | D3D11_BIND_INDEX_BUFFER;
2392
2393 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.pBuffer);
2394 if (SUCCEEDED(hr))
2395 {
2396 /*
2397 * Success.
2398 */
2399 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
2400 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
2401 pSurface->pBackendSurface = pBackendSurface;
2402 pSurface->idAssociatedContext = pDXContext->cid;
2403 return VINF_SUCCESS;
2404 }
2405
2406 /* Failure. */
2407 D3D_RELEASE(pBackendSurface->u.pBuffer);
2408 RTMemFree(pBackendSurface);
2409 return VERR_NO_MEMORY;
2410}
2411
2412
2413static int vmsvga3dBackSurfaceCreateSoBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
2414{
2415 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
2416 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
2417
2418 /* Buffers should be created as such. */
2419 AssertReturn(RT_BOOL(pSurface->surfaceFlags & SVGA3D_SURFACE_BIND_STREAM_OUTPUT), VERR_INVALID_PARAMETER);
2420
2421 if (pSurface->pBackendSurface != NULL)
2422 {
2423 AssertFailed(); /** @todo Should the function not be used like that? */
2424 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
2425 }
2426
2427 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2428 int rc = dxBackendSurfaceAlloc(&pBackendSurface);
2429 AssertRCReturn(rc, rc);
2430
2431 D3D11_BUFFER_DESC bd;
2432 RT_ZERO(bd);
2433 bd.ByteWidth = pSurface->paMipmapLevels[0].cbSurface;
2434 bd.Usage = D3D11_USAGE_DEFAULT;
2435 bd.BindFlags = dxBindFlags(pSurface->surfaceFlags); // D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_OUTPUT;
2436 bd.CPUAccessFlags = 0; /// @todo ? D3D11_CPU_ACCESS_READ;
2437 bd.MiscFlags = 0;
2438 bd.StructureByteStride = 0;
2439
2440 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, 0, &pBackendSurface->u.pBuffer);
2441 if (SUCCEEDED(hr))
2442 {
2443 /*
2444 * Success.
2445 */
2446 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
2447 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
2448 pSurface->pBackendSurface = pBackendSurface;
2449 pSurface->idAssociatedContext = pDXContext->cid;
2450 return VINF_SUCCESS;
2451 }
2452
2453 /* Failure. */
2454 D3D_RELEASE(pBackendSurface->u.pBuffer);
2455 RTMemFree(pBackendSurface);
2456 return VERR_NO_MEMORY;
2457}
2458
2459#if 0 /*unused*/
2460/** @todo Not needed */
2461static int vmsvga3dBackSurfaceCreateConstantBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
2462{
2463 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
2464 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
2465
2466 /* Buffers should be created as such. */
2467 AssertReturn(RT_BOOL(pSurface->surfaceFlags & ( SVGA3D_SURFACE_BIND_CONSTANT_BUFFER)), VERR_INVALID_PARAMETER);
2468
2469 if (pSurface->pBackendSurface != NULL)
2470 {
2471 AssertFailed(); /** @todo Should the function not be used like that? */
2472 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
2473 }
2474
2475 PVMSVGA3DMIPMAPLEVEL pMipLevel;
2476 int rc = vmsvga3dMipmapLevel(pSurface, 0, 0, &pMipLevel);
2477 AssertRCReturn(rc, rc);
2478
2479 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2480 rc = dxBackendSurfaceAlloc(&pBackendSurface);
2481 AssertRCReturn(rc, rc);
2482
2483 /* Upload the current data, if any. */
2484 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
2485 D3D11_SUBRESOURCE_DATA initialData;
2486 if (pMipLevel->pSurfaceData)
2487 {
2488 initialData.pSysMem = pMipLevel->pSurfaceData;
2489 initialData.SysMemPitch = pMipLevel->cbSurface;
2490 initialData.SysMemSlicePitch = pMipLevel->cbSurface;
2491
2492 pInitialData = &initialData;
2493 }
2494
2495 D3D11_BUFFER_DESC bd;
2496 RT_ZERO(bd);
2497 bd.ByteWidth = pMipLevel->cbSurface;
2498 bd.Usage = D3D11_USAGE_DYNAMIC;
2499 bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
2500 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2501 bd.MiscFlags = 0;
2502 bd.StructureByteStride = 0;
2503
2504 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.pBuffer);
2505 if (SUCCEEDED(hr))
2506 {
2507 /*
2508 * Success.
2509 */
2510 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
2511 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
2512 pSurface->pBackendSurface = pBackendSurface;
2513 pSurface->idAssociatedContext = pDXContext->cid;
2514 return VINF_SUCCESS;
2515 }
2516
2517 /* Failure. */
2518 D3D_RELEASE(pBackendSurface->u.pBuffer);
2519 RTMemFree(pBackendSurface);
2520 return VERR_NO_MEMORY;
2521}
2522
2523
2524static HRESULT dxCreateConstantBuffer(DXDEVICE *pDevice, VMSVGA3DSURFACE const *pSurface, PVMSVGA3DBACKENDSURFACE pBackendSurface)
2525{
2526 D3D11_SUBRESOURCE_DATA *pInitialData = NULL; /** @todo */
2527 D3D11_BUFFER_DESC bd;
2528 RT_ZERO(bd);
2529 bd.ByteWidth = pSurface->paMipmapLevels[0].cbSurface;
2530 bd.Usage = D3D11_USAGE_DYNAMIC; /** @todo HINT_STATIC */
2531 bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
2532 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2533 bd.MiscFlags = 0;
2534 bd.StructureByteStride = 0;
2535
2536 return pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.pBuffer);
2537}
2538
2539
2540static HRESULT dxCreateBuffer(DXDEVICE *pDevice, VMSVGA3DSURFACE const *pSurface, PVMSVGA3DBACKENDSURFACE pBackendSurface)
2541{
2542 D3D11_SUBRESOURCE_DATA *pInitialData = NULL; /** @todo */
2543 D3D11_BUFFER_DESC bd;
2544 RT_ZERO(bd);
2545 bd.ByteWidth = pSurface->paMipmapLevels[0].cbSurface;
2546 bd.Usage = D3D11_USAGE_DYNAMIC; /** @todo HINT_STATIC */
2547 bd.BindFlags = D3D11_BIND_VERTEX_BUFFER
2548 | D3D11_BIND_INDEX_BUFFER;
2549 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
2550 bd.MiscFlags = 0;
2551 bd.StructureByteStride = 0;
2552
2553 return pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBackendSurface->u.pBuffer);
2554}
2555
2556/** @todo Not needed? */
2557static int vmsvga3dBackSurfaceCreate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PVMSVGA3DSURFACE pSurface)
2558{
2559 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
2560 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
2561
2562 if (pSurface->pBackendSurface != NULL)
2563 {
2564 AssertFailed(); /** @todo Should the function not be used like that? */
2565 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
2566 }
2567
2568 PVMSVGA3DBACKENDSURFACE pBackendSurface;
2569 int rc = dxBackendSurfaceAlloc(&pBackendSurface);
2570 AssertRCReturn(rc, rc);
2571
2572 HRESULT hr;
2573
2574 /*
2575 * Figure out the type of the surface.
2576 */
2577 if (pSurface->surfaceFlags & SVGA3D_SURFACE_BIND_CONSTANT_BUFFER)
2578 {
2579 hr = dxCreateConstantBuffer(pDevice, pSurface, pBackendSurface);
2580 if (SUCCEEDED(hr))
2581 {
2582 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
2583 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
2584 }
2585 else
2586 D3D_RELEASE(pBackendSurface->u.pBuffer);
2587 }
2588 else if (pSurface->surfaceFlags & ( SVGA3D_SURFACE_BIND_VERTEX_BUFFER
2589 | SVGA3D_SURFACE_BIND_INDEX_BUFFER
2590 | SVGA3D_SURFACE_HINT_VERTEXBUFFER
2591 | SVGA3D_SURFACE_HINT_INDEXBUFFER))
2592 {
2593 hr = dxCreateBuffer(pDevice, pSurface, pBackendSurface);
2594 if (SUCCEEDED(hr))
2595 {
2596 pBackendSurface->enmResType = VMSVGA3D_RESTYPE_BUFFER;
2597 pBackendSurface->enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
2598 }
2599 else
2600 D3D_RELEASE(pBackendSurface->u.pBuffer);
2601 }
2602 else
2603 {
2604 AssertFailed(); /** @todo implement */
2605 hr = E_FAIL;
2606 }
2607
2608 if (SUCCEEDED(hr))
2609 {
2610 /*
2611 * Success.
2612 */
2613 pSurface->pBackendSurface = pBackendSurface;
2614 pSurface->idAssociatedContext = pDXContext->cid;
2615 return VINF_SUCCESS;
2616 }
2617
2618 /* Failure. */
2619 RTMemFree(pBackendSurface);
2620 return VERR_NO_MEMORY;
2621}
2622#endif
2623
2624
2625static int dxStagingBufferRealloc(DXDEVICE *pDXDevice, uint32_t cbRequiredSize)
2626{
2627 AssertReturn(cbRequiredSize < SVGA3D_MAX_SURFACE_MEM_SIZE, VERR_INVALID_PARAMETER);
2628
2629 if (RT_LIKELY(cbRequiredSize <= pDXDevice->cbStagingBuffer))
2630 return VINF_SUCCESS;
2631
2632 D3D_RELEASE(pDXDevice->pStagingBuffer);
2633
2634 uint32_t const cbAlloc = RT_ALIGN_32(cbRequiredSize, _64K);
2635
2636 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
2637 D3D11_BUFFER_DESC bd;
2638 RT_ZERO(bd);
2639 bd.ByteWidth = cbAlloc;
2640 bd.Usage = D3D11_USAGE_STAGING;
2641 //bd.BindFlags = 0; /* No bind flags are allowed for staging resources. */
2642 bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
2643
2644 int rc = VINF_SUCCESS;
2645 ID3D11Buffer *pBuffer;
2646 HRESULT hr = pDXDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBuffer);
2647 if (SUCCEEDED(hr))
2648 {
2649 pDXDevice->pStagingBuffer = pBuffer;
2650 pDXDevice->cbStagingBuffer = cbAlloc;
2651 }
2652 else
2653 {
2654 pDXDevice->cbStagingBuffer = 0;
2655 rc = VERR_NO_MEMORY;
2656 }
2657
2658 return rc;
2659}
2660
2661
2662static DECLCALLBACK(int) vmsvga3dBackInit(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC)
2663{
2664 RT_NOREF(pDevIns, pThis);
2665
2666 int rc;
2667#ifdef RT_OS_LINUX /** @todo Remove, this is currently needed for loading the X11 library in order to call XInitThreads(). */
2668 rc = glLdrInit(pDevIns);
2669 if (RT_FAILURE(rc))
2670 {
2671 LogRel(("VMSVGA3d: Error loading OpenGL library and resolving necessary functions: %Rrc\n", rc));
2672 return rc;
2673 }
2674#endif
2675
2676 PVMSVGA3DSTATE pState = (PVMSVGA3DSTATE)RTMemAllocZ(sizeof(VMSVGA3DSTATE));
2677 AssertReturn(pState, VERR_NO_MEMORY);
2678 pThisCC->svga.p3dState = pState;
2679
2680 PVMSVGA3DBACKEND pBackend = (PVMSVGA3DBACKEND)RTMemAllocZ(sizeof(VMSVGA3DBACKEND));
2681 AssertReturn(pBackend, VERR_NO_MEMORY);
2682 pState->pBackend = pBackend;
2683
2684 rc = RTLdrLoadSystem(VBOX_D3D11_LIBRARY_NAME, /* fNoUnload = */ true, &pBackend->hD3D11);
2685 AssertRC(rc);
2686 if (RT_SUCCESS(rc))
2687 {
2688 rc = RTLdrGetSymbol(pBackend->hD3D11, "D3D11CreateDevice", (void **)&pBackend->pfnD3D11CreateDevice);
2689 AssertRC(rc);
2690 }
2691
2692 if (RT_SUCCESS(rc))
2693 {
2694 /* Failure to load the shader disassembler is ignored. */
2695 int rc2 = RTLdrLoadSystem("D3DCompiler_47", /* fNoUnload = */ true, &pBackend->hD3DCompiler);
2696 if (RT_SUCCESS(rc2))
2697 rc2 = RTLdrGetSymbol(pBackend->hD3DCompiler, "D3DDisassemble", (void **)&pBackend->pfnD3DDisassemble);
2698 Log6Func(("Load D3DDisassemble: %Rrc\n", rc2));
2699 }
2700
2701#if !defined(RT_OS_WINDOWS) || defined(DX_FORCE_SINGLE_DEVICE)
2702 pBackend->fSingleDevice = true;
2703#endif
2704
2705 LogRelMax(1, ("VMSVGA: Single DX device mode: %s\n", pBackend->fSingleDevice ? "enabled" : "disabled"));
2706
2707//DEBUG_BREAKPOINT_TEST();
2708 return rc;
2709}
2710
2711
2712static DECLCALLBACK(int) vmsvga3dBackPowerOn(PPDMDEVINS pDevIns, PVGASTATE pThis, PVGASTATECC pThisCC)
2713{
2714 RT_NOREF(pDevIns, pThis);
2715
2716 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
2717 AssertReturn(pState, VERR_INVALID_STATE);
2718
2719 PVMSVGA3DBACKEND pBackend = pState->pBackend;
2720 AssertReturn(pBackend, VERR_INVALID_STATE);
2721
2722 int rc = dxDeviceCreate(pBackend, &pBackend->dxDevice);
2723 if (RT_SUCCESS(rc))
2724 {
2725 IDXGIAdapter *pAdapter = NULL;
2726 HRESULT hr = pBackend->dxDevice.pDxgiFactory->EnumAdapters(0, &pAdapter);
2727 if (SUCCEEDED(hr))
2728 {
2729 DXGI_ADAPTER_DESC desc;
2730 hr = pAdapter->GetDesc(&desc);
2731 if (SUCCEEDED(hr))
2732 {
2733 char sz[RT_ELEMENTS(desc.Description)];
2734 for (unsigned i = 0; i < RT_ELEMENTS(desc.Description); ++i)
2735 sz[i] = (char)desc.Description[i];
2736 LogRelMax(1, ("VMSVGA: Adapter [%s]\n", sz));
2737 }
2738
2739 pAdapter->Release();
2740 }
2741 }
2742 return rc;
2743}
2744
2745
2746static DECLCALLBACK(int) vmsvga3dBackReset(PVGASTATECC pThisCC)
2747{
2748 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
2749 AssertReturn(pState, VERR_INVALID_STATE);
2750
2751 /** @todo This is generic code. Must be moved to in DevVGA-SVGA3d.cpp */
2752 /* Destroy all leftover surfaces. */
2753 for (uint32_t i = 0; i < pState->cSurfaces; i++)
2754 {
2755 if (pState->papSurfaces[i]->id != SVGA3D_INVALID_ID)
2756 vmsvga3dSurfaceDestroy(pThisCC, pState->papSurfaces[i]->id);
2757 }
2758
2759 /* Destroy all leftover DX contexts. */
2760 for (uint32_t i = 0; i < pState->cDXContexts; i++)
2761 {
2762 if (pState->papDXContexts[i]->cid != SVGA3D_INVALID_ID)
2763 vmsvga3dDXDestroyContext(pThisCC, pState->papDXContexts[i]->cid);
2764 }
2765
2766 return VINF_SUCCESS;
2767}
2768
2769
2770static DECLCALLBACK(int) vmsvga3dBackTerminate(PVGASTATECC pThisCC)
2771{
2772 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
2773 AssertReturn(pState, VERR_INVALID_STATE);
2774
2775 if (pState->pBackend)
2776 {
2777 /* Clean up backends. For example release resources from surfaces. */
2778 vmsvga3dBackReset(pThisCC);
2779
2780 dxDeviceDestroy(pState->pBackend, &pState->pBackend->dxDevice);
2781
2782 RTMemFree(pState->pBackend);
2783 pState->pBackend = NULL;
2784 }
2785
2786 return VINF_SUCCESS;
2787}
2788
2789
2790/** @todo Such structures must be in VBoxVideo3D.h */
2791typedef struct VBOX3DNOTIFYDEFINESCREEN
2792{
2793 VBOX3DNOTIFY Core;
2794 uint32_t cWidth;
2795 uint32_t cHeight;
2796 int32_t xRoot;
2797 int32_t yRoot;
2798 uint32_t fPrimary;
2799 uint32_t cDpi;
2800} VBOX3DNOTIFYDEFINESCREEN;
2801
2802
2803static int vmsvga3dDrvNotifyDefineScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
2804{
2805 VBOX3DNOTIFYDEFINESCREEN n;
2806 n.Core.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_CREATED;
2807 n.Core.iDisplay = pScreen->idScreen;
2808 n.Core.u32Reserved = 0;
2809 n.Core.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
2810 RT_ZERO(n.Core.au8Data);
2811 n.cWidth = pScreen->cWidth;
2812 n.cHeight = pScreen->cHeight;
2813 n.xRoot = pScreen->xOrigin;
2814 n.yRoot = pScreen->yOrigin;
2815 n.fPrimary = RT_BOOL(pScreen->fuScreen & SVGA_SCREEN_IS_PRIMARY);
2816 n.cDpi = pScreen->cDpi;
2817
2818 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n.Core);
2819}
2820
2821
2822static int vmsvga3dDrvNotifyDestroyScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
2823{
2824 VBOX3DNOTIFY n;
2825 n.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_DESTROYED;
2826 n.iDisplay = pScreen->idScreen;
2827 n.u32Reserved = 0;
2828 n.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
2829 RT_ZERO(n.au8Data);
2830
2831 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n);
2832}
2833
2834
2835static int vmsvga3dDrvNotifyBindSurface(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, HANDLE hSharedSurface)
2836{
2837 VBOX3DNOTIFY n;
2838 n.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_BIND_SURFACE;
2839 n.iDisplay = pScreen->idScreen;
2840 n.u32Reserved = 0;
2841 n.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
2842 *(uint64_t *)&n.au8Data[0] = (uint64_t)hSharedSurface;
2843
2844 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n);
2845}
2846
2847
2848typedef struct VBOX3DNOTIFYUPDATE
2849{
2850 VBOX3DNOTIFY Core;
2851 uint32_t x;
2852 uint32_t y;
2853 uint32_t w;
2854 uint32_t h;
2855} VBOX3DNOTIFYUPDATE;
2856
2857
2858static int vmsvga3dDrvNotifyUpdate(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen,
2859 uint32_t x, uint32_t y, uint32_t w, uint32_t h)
2860{
2861 VBOX3DNOTIFYUPDATE n;
2862 n.Core.enmNotification = VBOX3D_NOTIFY_TYPE_HW_SCREEN_UPDATE_END;
2863 n.Core.iDisplay = pScreen->idScreen;
2864 n.Core.u32Reserved = 0;
2865 n.Core.cbData = sizeof(n) - RT_UOFFSETOF(VBOX3DNOTIFY, au8Data);
2866 RT_ZERO(n.Core.au8Data);
2867 n.x = x;
2868 n.y = y;
2869 n.w = w;
2870 n.h = h;
2871
2872 return pThisCC->pDrv->pfn3DNotifyProcess(pThisCC->pDrv, &n.Core);
2873}
2874
2875static int vmsvga3dHwScreenCreate(PVMSVGA3DSTATE pState, uint32_t cWidth, uint32_t cHeight, VMSVGAHWSCREEN *p)
2876{
2877 PVMSVGA3DBACKEND pBackend = pState->pBackend;
2878
2879 DXDEVICE *pDXDevice = &pBackend->dxDevice;
2880 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
2881
2882 D3D11_TEXTURE2D_DESC td;
2883 RT_ZERO(td);
2884 td.Width = cWidth;
2885 td.Height = cHeight;
2886 td.MipLevels = 1;
2887 td.ArraySize = 1;
2888 td.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
2889 td.SampleDesc.Count = 1;
2890 td.SampleDesc.Quality = 0;
2891 td.Usage = D3D11_USAGE_DEFAULT;
2892 td.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
2893 td.CPUAccessFlags = 0;
2894 td.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
2895
2896 HRESULT hr = pDXDevice->pDevice->CreateTexture2D(&td, 0, &p->pTexture);
2897 if (SUCCEEDED(hr))
2898 {
2899 /* Get the shared handle. */
2900 hr = p->pTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&p->pDxgiResource);
2901 if (SUCCEEDED(hr))
2902 {
2903 hr = p->pDxgiResource->GetSharedHandle(&p->SharedHandle);
2904 if (SUCCEEDED(hr))
2905 hr = p->pTexture->QueryInterface(__uuidof(IDXGIKeyedMutex), (void**)&p->pDXGIKeyedMutex);
2906 }
2907 }
2908
2909 if (SUCCEEDED(hr))
2910 return VINF_SUCCESS;
2911
2912 AssertFailed();
2913 return VERR_NOT_SUPPORTED;
2914}
2915
2916
2917static void vmsvga3dHwScreenDestroy(PVMSVGA3DSTATE pState, VMSVGAHWSCREEN *p)
2918{
2919 RT_NOREF(pState);
2920 D3D_RELEASE(p->pDXGIKeyedMutex);
2921 D3D_RELEASE(p->pDxgiResource);
2922 D3D_RELEASE(p->pTexture);
2923 p->SharedHandle = 0;
2924 p->sidScreenTarget = SVGA_ID_INVALID;
2925}
2926
2927
2928static DECLCALLBACK(int) vmsvga3dBackDefineScreen(PVGASTATE pThis, PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
2929{
2930 RT_NOREF(pThis, pThisCC, pScreen);
2931
2932 LogRel4(("VMSVGA: vmsvga3dBackDefineScreen: screen %u\n", pScreen->idScreen));
2933
2934 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
2935 AssertReturn(pState, VERR_INVALID_STATE);
2936
2937 PVMSVGA3DBACKEND pBackend = pState->pBackend;
2938 AssertReturn(pBackend, VERR_INVALID_STATE);
2939
2940 Assert(pScreen->pHwScreen == NULL);
2941
2942 VMSVGAHWSCREEN *p = (VMSVGAHWSCREEN *)RTMemAllocZ(sizeof(VMSVGAHWSCREEN));
2943 AssertPtrReturn(p, VERR_NO_MEMORY);
2944
2945 p->sidScreenTarget = SVGA_ID_INVALID;
2946
2947 int rc = vmsvga3dDrvNotifyDefineScreen(pThisCC, pScreen);
2948 if (RT_SUCCESS(rc))
2949 {
2950 /* The frontend supports the screen. Create the actual resource. */
2951 rc = vmsvga3dHwScreenCreate(pState, pScreen->cWidth, pScreen->cHeight, p);
2952 if (RT_SUCCESS(rc))
2953 LogRel4(("VMSVGA: vmsvga3dBackDefineScreen: created\n"));
2954 }
2955
2956 if (RT_SUCCESS(rc))
2957 {
2958 LogRel(("VMSVGA: Using HW accelerated screen %u\n", pScreen->idScreen));
2959 pScreen->pHwScreen = p;
2960 }
2961 else
2962 {
2963 LogRel4(("VMSVGA: vmsvga3dBackDefineScreen: %Rrc\n", rc));
2964 vmsvga3dHwScreenDestroy(pState, p);
2965 RTMemFree(p);
2966 }
2967
2968 return rc;
2969}
2970
2971
2972static DECLCALLBACK(int) vmsvga3dBackDestroyScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen)
2973{
2974 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
2975 AssertReturn(pState, VERR_INVALID_STATE);
2976
2977 vmsvga3dDrvNotifyDestroyScreen(pThisCC, pScreen);
2978
2979 if (pScreen->pHwScreen)
2980 {
2981 vmsvga3dHwScreenDestroy(pState, pScreen->pHwScreen);
2982 RTMemFree(pScreen->pHwScreen);
2983 pScreen->pHwScreen = NULL;
2984 }
2985
2986 return VINF_SUCCESS;
2987}
2988
2989
2990static DECLCALLBACK(int) vmsvga3dBackSurfaceBlitToScreen(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen,
2991 SVGASignedRect destRect, SVGA3dSurfaceImageId srcImage,
2992 SVGASignedRect srcRect, uint32_t cRects, SVGASignedRect *paRects)
2993{
2994 RT_NOREF(pThisCC, pScreen, destRect, srcImage, srcRect, cRects, paRects);
2995
2996 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
2997 AssertReturn(pState, VERR_INVALID_STATE);
2998
2999 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3000 AssertReturn(pBackend, VERR_INVALID_STATE);
3001
3002 VMSVGAHWSCREEN *p = pScreen->pHwScreen;
3003 AssertReturn(p, VERR_NOT_SUPPORTED);
3004
3005 PVMSVGA3DSURFACE pSurface;
3006 int rc = vmsvga3dSurfaceFromSid(pState, srcImage.sid, &pSurface);
3007 AssertRCReturn(rc, rc);
3008
3009 /** @todo Implement. */
3010 AssertFailed();
3011 return VERR_NOT_IMPLEMENTED;
3012}
3013
3014
3015static DECLCALLBACK(int) vmsvga3dBackSurfaceMap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, SVGA3dBox const *pBox,
3016 VMSVGA3D_SURFACE_MAP enmMapType, VMSVGA3D_MAPPED_SURFACE *pMap)
3017{
3018 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3019 AssertReturn(pState, VERR_INVALID_STATE);
3020
3021 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3022 AssertReturn(pBackend, VERR_INVALID_STATE);
3023
3024 PVMSVGA3DSURFACE pSurface;
3025 int rc = vmsvga3dSurfaceFromSid(pState, pImage->sid, &pSurface);
3026 AssertRCReturn(rc, rc);
3027
3028 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
3029 AssertPtrReturn(pBackendSurface, VERR_INVALID_STATE);
3030
3031 PVMSVGA3DMIPMAPLEVEL pMipLevel;
3032 rc = vmsvga3dMipmapLevel(pSurface, pImage->face, pImage->mipmap, &pMipLevel);
3033 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
3034
3035 /* A surface is always mapped by the DX context which has created the surface. */
3036 DXDEVICE *pDevice = dxDeviceFromCid(pSurface->idAssociatedContext, pState);
3037 AssertReturn(pDevice && pDevice->pDevice, VERR_INVALID_STATE);
3038
3039 SVGA3dBox clipBox;
3040 if (pBox)
3041 {
3042 clipBox = *pBox;
3043 vmsvgaR3ClipBox(&pMipLevel->mipmapSize, &clipBox);
3044 ASSERT_GUEST_RETURN(clipBox.w && clipBox.h && clipBox.d, VERR_INVALID_PARAMETER);
3045 }
3046 else
3047 {
3048 clipBox.x = 0;
3049 clipBox.y = 0;
3050 clipBox.z = 0;
3051 clipBox.w = pMipLevel->mipmapSize.width;
3052 clipBox.h = pMipLevel->mipmapSize.height;
3053 clipBox.d = pMipLevel->mipmapSize.depth;
3054 }
3055
3056 D3D11_MAP d3d11MapType;
3057 switch (enmMapType)
3058 {
3059 case VMSVGA3D_SURFACE_MAP_READ: d3d11MapType = D3D11_MAP_READ; break;
3060 case VMSVGA3D_SURFACE_MAP_WRITE: d3d11MapType = D3D11_MAP_WRITE; break;
3061 case VMSVGA3D_SURFACE_MAP_READ_WRITE: d3d11MapType = D3D11_MAP_READ_WRITE; break;
3062 case VMSVGA3D_SURFACE_MAP_WRITE_DISCARD: d3d11MapType = D3D11_MAP_WRITE_DISCARD; break;
3063 default:
3064 AssertFailed();
3065 return VERR_INVALID_PARAMETER;
3066 }
3067
3068 D3D11_MAPPED_SUBRESOURCE mappedResource;
3069 RT_ZERO(mappedResource);
3070
3071 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
3072 {
3073 Assert(pImage->face == 0 && pImage->mipmap == 0);
3074
3075 /* Wait for the surface to finish drawing. */
3076 dxSurfaceWait(pState, pSurface, pSurface->idAssociatedContext);
3077
3078 ID3D11Texture2D *pMappedTexture;
3079 if (enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3080 {
3081 pMappedTexture = pBackendSurface->staging.pTexture2D;
3082
3083 /* Copy the texture content to the staging texture. */
3084 pDevice->pImmediateContext->CopyResource(pBackendSurface->staging.pTexture2D, pBackendSurface->u.pTexture2D);
3085 }
3086 else if (enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
3087 pMappedTexture = pBackendSurface->staging.pTexture2D;
3088 else
3089 pMappedTexture = pBackendSurface->dynamic.pTexture2D;
3090
3091 UINT const Subresource = 0; /* Screen target surfaces have only one subresource. */
3092 HRESULT hr = pDevice->pImmediateContext->Map(pMappedTexture, Subresource,
3093 d3d11MapType, /* MapFlags = */ 0, &mappedResource);
3094 if (SUCCEEDED(hr))
3095 {
3096 pMap->enmMapType = enmMapType;
3097 pMap->format = pSurface->format;
3098 pMap->box = clipBox;
3099 pMap->cbPixel = pSurface->cbBlock;
3100 pMap->cbRowPitch = mappedResource.RowPitch;
3101 pMap->cbDepthPitch = mappedResource.DepthPitch;
3102 pMap->pvData = (uint8_t *)mappedResource.pData
3103 + pMap->box.x * pMap->cbPixel
3104 + pMap->box.y * pMap->cbRowPitch
3105 + pMap->box.z * pMap->cbDepthPitch;
3106 }
3107 else
3108 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
3109 }
3110 else if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_1D
3111 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
3112 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_CUBE
3113 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3114 {
3115 dxSurfaceWait(pState, pSurface, pSurface->idAssociatedContext);
3116
3117 ID3D11Resource *pMappedResource;
3118 if (enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3119 {
3120 pMappedResource = pBackendSurface->staging.pResource;
3121
3122 /* Copy the texture content to the staging texture.
3123 * The requested miplevel of the texture is copied to the miplevel 0 of the staging texture,
3124 * because the staging (and dynamic) structures do not have miplevels.
3125 * Always copy entire miplevel so all Dst are zero and pSrcBox is NULL, as D3D11 requires.
3126 */
3127 ID3D11Resource *pDstResource = pMappedResource;
3128 UINT DstSubresource = 0;
3129 UINT DstX = 0;
3130 UINT DstY = 0;
3131 UINT DstZ = 0;
3132 ID3D11Resource *pSrcResource = pBackendSurface->u.pResource;
3133 UINT SrcSubresource = D3D11CalcSubresource(pImage->mipmap, pImage->face, pSurface->cLevels);
3134 D3D11_BOX *pSrcBox = NULL;
3135 //D3D11_BOX SrcBox;
3136 //SrcBox.left = 0;
3137 //SrcBox.top = 0;
3138 //SrcBox.front = 0;
3139 //SrcBox.right = pMipLevel->mipmapSize.width;
3140 //SrcBox.bottom = pMipLevel->mipmapSize.height;
3141 //SrcBox.back = pMipLevel->mipmapSize.depth;
3142 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3143 pSrcResource, SrcSubresource, pSrcBox);
3144 }
3145 else if (enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
3146 pMappedResource = pBackendSurface->staging.pResource;
3147 else
3148 pMappedResource = pBackendSurface->dynamic.pResource;
3149
3150 UINT const Subresource = 0;
3151 HRESULT hr = pDevice->pImmediateContext->Map(pMappedResource, Subresource,
3152 d3d11MapType, /* MapFlags = */ 0, &mappedResource);
3153 if (SUCCEEDED(hr))
3154 {
3155 pMap->enmMapType = enmMapType;
3156 pMap->format = pSurface->format;
3157 pMap->box = clipBox;
3158 pMap->cbPixel = pSurface->cbBlock;
3159 pMap->cbRowPitch = mappedResource.RowPitch;
3160 pMap->cbDepthPitch = mappedResource.DepthPitch;
3161 pMap->pvData = (uint8_t *)mappedResource.pData
3162 + (pMap->box.x / pSurface->cxBlock) * pMap->cbPixel
3163 + (pMap->box.y / pSurface->cyBlock) * pMap->cbRowPitch
3164 + pMap->box.z * pMap->cbDepthPitch;
3165 }
3166 else
3167 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
3168 }
3169 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
3170 {
3171 /* Map the staging buffer. */
3172 rc = dxStagingBufferRealloc(pDevice, pMipLevel->cbSurface);
3173 if (RT_SUCCESS(rc))
3174 {
3175 /* The staging buffer does not allow D3D11_MAP_WRITE_DISCARD, so replace it. */
3176 if (d3d11MapType == D3D11_MAP_WRITE_DISCARD)
3177 d3d11MapType = D3D11_MAP_WRITE;
3178
3179 if (enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3180 {
3181 /* Copy from the buffer to the staging buffer. */
3182 ID3D11Resource *pDstResource = pDevice->pStagingBuffer;
3183 UINT DstSubresource = 0;
3184 UINT DstX = clipBox.x;
3185 UINT DstY = clipBox.y;
3186 UINT DstZ = clipBox.z;
3187 ID3D11Resource *pSrcResource = pBackendSurface->u.pResource;
3188 UINT SrcSubresource = 0;
3189 D3D11_BOX SrcBox;
3190 SrcBox.left = clipBox.x;
3191 SrcBox.top = clipBox.y;
3192 SrcBox.front = clipBox.z;
3193 SrcBox.right = clipBox.w;
3194 SrcBox.bottom = clipBox.h;
3195 SrcBox.back = clipBox.d;
3196 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3197 pSrcResource, SrcSubresource, &SrcBox);
3198 }
3199
3200 UINT const Subresource = 0; /* Buffers have only one subresource. */
3201 HRESULT hr = pDevice->pImmediateContext->Map(pDevice->pStagingBuffer, Subresource,
3202 d3d11MapType, /* MapFlags = */ 0, &mappedResource);
3203 if (SUCCEEDED(hr))
3204 {
3205 pMap->enmMapType = enmMapType;
3206 pMap->format = pSurface->format;
3207 pMap->box = clipBox;
3208 pMap->cbPixel = pSurface->cbBlock;
3209 pMap->cbRowPitch = mappedResource.RowPitch;
3210 pMap->cbDepthPitch = mappedResource.DepthPitch;
3211 pMap->pvData = (uint8_t *)mappedResource.pData
3212 + pMap->box.x * pMap->cbPixel
3213 + pMap->box.y * pMap->cbRowPitch
3214 + pMap->box.z * pMap->cbDepthPitch;
3215 }
3216 else
3217 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
3218 }
3219 }
3220 else
3221 {
3222 // UINT D3D11CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT MipLevels);
3223 /** @todo Implement. */
3224 AssertFailed();
3225 rc = VERR_NOT_IMPLEMENTED;
3226 }
3227
3228 return rc;
3229}
3230
3231
3232static DECLCALLBACK(int) vmsvga3dBackSurfaceUnmap(PVGASTATECC pThisCC, SVGA3dSurfaceImageId const *pImage, VMSVGA3D_MAPPED_SURFACE *pMap, bool fWritten)
3233{
3234 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3235 AssertReturn(pState, VERR_INVALID_STATE);
3236
3237 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3238 AssertReturn(pBackend, VERR_INVALID_STATE);
3239
3240 PVMSVGA3DSURFACE pSurface;
3241 int rc = vmsvga3dSurfaceFromSid(pState, pImage->sid, &pSurface);
3242 AssertRCReturn(rc, rc);
3243
3244 /* The called should not use the function for system memory surfaces. */
3245 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
3246 AssertReturn(pBackendSurface, VERR_INVALID_PARAMETER);
3247
3248 PVMSVGA3DMIPMAPLEVEL pMipLevel;
3249 rc = vmsvga3dMipmapLevel(pSurface, pImage->face, pImage->mipmap, &pMipLevel);
3250 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
3251
3252 /* A surface is always mapped by the DX context which has created the surface. */
3253 DXDEVICE *pDevice = dxDeviceFromCid(pSurface->idAssociatedContext, pState);
3254 AssertReturn(pDevice && pDevice->pDevice, VERR_INVALID_STATE);
3255
3256 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
3257 {
3258 ID3D11Texture2D *pMappedTexture;
3259 if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3260 pMappedTexture = pBackendSurface->staging.pTexture2D;
3261 else if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
3262 pMappedTexture = pBackendSurface->staging.pTexture2D;
3263 else
3264 pMappedTexture = pBackendSurface->dynamic.pTexture2D;
3265
3266 UINT const Subresource = 0; /* Screen target surfaces have only one subresource. */
3267 pDevice->pImmediateContext->Unmap(pMappedTexture, Subresource);
3268
3269 if ( fWritten
3270 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
3271 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
3272 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
3273 {
3274 ID3D11Resource *pDstResource = pBackendSurface->u.pTexture2D;
3275 UINT DstSubresource = Subresource;
3276 UINT DstX = pMap->box.x;
3277 UINT DstY = pMap->box.y;
3278 UINT DstZ = pMap->box.z;
3279 ID3D11Resource *pSrcResource = pMappedTexture;
3280 UINT SrcSubresource = Subresource;
3281 D3D11_BOX SrcBox;
3282 SrcBox.left = pMap->box.x;
3283 SrcBox.top = pMap->box.y;
3284 SrcBox.front = pMap->box.z;
3285 SrcBox.right = pMap->box.x + pMap->box.w;
3286 SrcBox.bottom = pMap->box.y + pMap->box.h;
3287 SrcBox.back = pMap->box.z + pMap->box.d;
3288
3289 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3290 pSrcResource, SrcSubresource, &SrcBox);
3291
3292 pBackendSurface->cidDrawing = pSurface->idAssociatedContext;
3293 }
3294 }
3295 else if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_1D
3296 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
3297 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_CUBE
3298 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
3299 {
3300 ID3D11Resource *pMappedResource;
3301 if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ)
3302 pMappedResource = pBackendSurface->staging.pResource;
3303 else if (pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE)
3304 pMappedResource = pBackendSurface->staging.pResource;
3305 else
3306 pMappedResource = pBackendSurface->dynamic.pResource;
3307
3308 UINT const Subresource = 0; /* Staging or dynamic textures have one subresource. */
3309 pDevice->pImmediateContext->Unmap(pMappedResource, Subresource);
3310
3311 if ( fWritten
3312 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
3313 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
3314 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
3315 {
3316 /* If entire resource must be copied then use pSrcBox = NULL and dst point (0,0,0)
3317 * Because DX11 insists on this for some resource types, for example DEPTH_STENCIL resources.
3318 */
3319 uint32_t const cWidth0 = pSurface->paMipmapLevels[0].mipmapSize.width;
3320 uint32_t const cHeight0 = pSurface->paMipmapLevels[0].mipmapSize.height;
3321 uint32_t const cDepth0 = pSurface->paMipmapLevels[0].mipmapSize.depth;
3322 bool const fEntireResource = pMap->box.x == 0 && pMap->box.y == 0 && pMap->box.z == 0
3323 && pMap->box.w == cWidth0 && pMap->box.h == cHeight0 && pMap->box.d == cDepth0;
3324
3325 ID3D11Resource *pDstResource = pBackendSurface->u.pResource;
3326 UINT DstSubresource = D3D11CalcSubresource(pImage->mipmap, pImage->face, pSurface->cLevels);
3327 UINT DstX = (pMap->box.x / pSurface->cxBlock) * pSurface->cxBlock;
3328 UINT DstY = (pMap->box.y / pSurface->cyBlock) * pSurface->cyBlock;
3329 UINT DstZ = pMap->box.z;
3330 ID3D11Resource *pSrcResource = pMappedResource;
3331 UINT SrcSubresource = Subresource;
3332 D3D11_BOX *pSrcBox;
3333 D3D11_BOX SrcBox;
3334 if (fEntireResource)
3335 pSrcBox = NULL;
3336 else
3337 {
3338 uint32_t const cxBlocks = (pMap->box.w + pSurface->cxBlock - 1) / pSurface->cxBlock;
3339 uint32_t const cyBlocks = (pMap->box.h + pSurface->cyBlock - 1) / pSurface->cyBlock;
3340
3341 SrcBox.left = DstX;
3342 SrcBox.top = DstY;
3343 SrcBox.front = DstZ;
3344 SrcBox.right = DstX + cxBlocks * pSurface->cxBlock;
3345 SrcBox.bottom = DstY + cyBlocks * pSurface->cyBlock;
3346 SrcBox.back = DstZ + pMap->box.d;
3347 pSrcBox = &SrcBox;
3348 }
3349
3350 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3351 pSrcResource, SrcSubresource, pSrcBox);
3352
3353 pBackendSurface->cidDrawing = pSurface->idAssociatedContext;
3354 }
3355 }
3356 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
3357 {
3358 /* Unmap the staging buffer. */
3359 UINT const Subresource = 0; /* Buffers have only one subresource. */
3360 pDevice->pImmediateContext->Unmap(pDevice->pStagingBuffer, Subresource);
3361
3362 /* Copy from the staging buffer to the actual buffer */
3363 if ( fWritten
3364 && ( pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE
3365 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_READ_WRITE
3366 || pMap->enmMapType == VMSVGA3D_SURFACE_MAP_WRITE_DISCARD))
3367 {
3368 ID3D11Resource *pDstResource = pBackendSurface->u.pResource;
3369 UINT DstSubresource = 0;
3370 UINT DstX = (pMap->box.x / pSurface->cxBlock) * pSurface->cxBlock;
3371 UINT DstY = (pMap->box.y / pSurface->cyBlock) * pSurface->cyBlock;
3372 UINT DstZ = pMap->box.z;
3373 ID3D11Resource *pSrcResource = pDevice->pStagingBuffer;
3374 UINT SrcSubresource = 0;
3375 D3D11_BOX SrcBox;
3376
3377 uint32_t const cxBlocks = (pMap->box.w + pSurface->cxBlock - 1) / pSurface->cxBlock;
3378 uint32_t const cyBlocks = (pMap->box.h + pSurface->cyBlock - 1) / pSurface->cyBlock;
3379
3380 SrcBox.left = DstX;
3381 SrcBox.top = DstY;
3382 SrcBox.front = DstZ;
3383 SrcBox.right = DstX + cxBlocks * pSurface->cxBlock;
3384 SrcBox.bottom = DstY + cyBlocks * pSurface->cyBlock;
3385 SrcBox.back = DstZ + pMap->box.d;
3386
3387 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
3388 pSrcResource, SrcSubresource, &SrcBox);
3389 }
3390 }
3391 else
3392 {
3393 AssertFailed();
3394 rc = VERR_NOT_IMPLEMENTED;
3395 }
3396
3397 return rc;
3398}
3399
3400
3401static DECLCALLBACK(int) vmsvga3dScreenTargetBind(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, uint32_t sid)
3402{
3403 int rc = VINF_SUCCESS;
3404
3405 PVMSVGA3DSURFACE pSurface;
3406 if (sid != SVGA_ID_INVALID)
3407 {
3408 /* Create the surface if does not yet exist. */
3409 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3410 AssertReturn(pState, VERR_INVALID_STATE);
3411
3412 rc = vmsvga3dSurfaceFromSid(pState, sid, &pSurface);
3413 AssertRCReturn(rc, rc);
3414
3415 if (!VMSVGA3DSURFACE_HAS_HW_SURFACE(pSurface))
3416 {
3417 /* Create the actual texture. */
3418 rc = vmsvga3dBackSurfaceCreateScreenTarget(pThisCC, pSurface);
3419 AssertRCReturn(rc, rc);
3420 }
3421 }
3422 else
3423 pSurface = NULL;
3424
3425 /* Notify the HW accelerated screen if it is used. */
3426 VMSVGAHWSCREEN *pHwScreen = pScreen->pHwScreen;
3427 if (!pHwScreen)
3428 return VINF_SUCCESS;
3429
3430 /* Same surface -> do nothing. */
3431 if (pHwScreen->sidScreenTarget == sid)
3432 return VINF_SUCCESS;
3433
3434 if (sid != SVGA_ID_INVALID)
3435 {
3436 AssertReturn( pSurface->pBackendSurface
3437 && pSurface->pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET, VERR_INVALID_PARAMETER);
3438
3439 HANDLE const hSharedSurface = pHwScreen->SharedHandle;
3440 rc = vmsvga3dDrvNotifyBindSurface(pThisCC, pScreen, hSharedSurface);
3441 }
3442
3443 if (RT_SUCCESS(rc))
3444 {
3445 pHwScreen->sidScreenTarget = sid;
3446 }
3447
3448 return rc;
3449}
3450
3451
3452static DECLCALLBACK(int) vmsvga3dScreenTargetUpdate(PVGASTATECC pThisCC, VMSVGASCREENOBJECT *pScreen, SVGA3dRect const *pRect)
3453{
3454 VMSVGAHWSCREEN *pHwScreen = pScreen->pHwScreen;
3455 AssertReturn(pHwScreen, VERR_NOT_SUPPORTED);
3456
3457 if (pHwScreen->sidScreenTarget == SVGA_ID_INVALID)
3458 return VINF_SUCCESS; /* No surface bound. */
3459
3460 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3461 AssertReturn(pState, VERR_INVALID_STATE);
3462
3463 PVMSVGA3DBACKEND pBackend = pState->pBackend;
3464 AssertReturn(pBackend, VERR_INVALID_STATE);
3465
3466 PVMSVGA3DSURFACE pSurface;
3467 int rc = vmsvga3dSurfaceFromSid(pState, pHwScreen->sidScreenTarget, &pSurface);
3468 AssertRCReturn(rc, rc);
3469
3470 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
3471 AssertReturn(pBackendSurface && pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET, VERR_INVALID_PARAMETER);
3472
3473 SVGA3dRect boundRect;
3474 boundRect.x = 0;
3475 boundRect.y = 0;
3476 boundRect.w = pSurface->paMipmapLevels[0].mipmapSize.width;
3477 boundRect.h = pSurface->paMipmapLevels[0].mipmapSize.height;
3478 SVGA3dRect clipRect = *pRect;
3479 vmsvgaR3Clip3dRect(&boundRect, &clipRect);
3480 ASSERT_GUEST_RETURN(clipRect.w && clipRect.h, VERR_INVALID_PARAMETER);
3481
3482 /* Wait for the surface to finish drawing. */
3483 dxSurfaceWait(pState, pSurface, DX_CID_BACKEND);
3484
3485 /* Copy the screen texture to the shared surface. */
3486 DWORD result = pHwScreen->pDXGIKeyedMutex->AcquireSync(0, 10000);
3487 if (result == S_OK)
3488 {
3489 pBackend->dxDevice.pImmediateContext->CopyResource(pHwScreen->pTexture, pBackendSurface->u.pTexture2D);
3490
3491 dxDeviceFlush(&pBackend->dxDevice);
3492
3493 result = pHwScreen->pDXGIKeyedMutex->ReleaseSync(1);
3494 }
3495 else
3496 AssertFailed();
3497
3498 rc = vmsvga3dDrvNotifyUpdate(pThisCC, pScreen, pRect->x, pRect->y, pRect->w, pRect->h);
3499 return rc;
3500}
3501
3502
3503/*
3504 *
3505 * 3D interface.
3506 *
3507 */
3508
3509static DECLCALLBACK(int) vmsvga3dBackQueryCaps(PVGASTATECC pThisCC, SVGA3dDevCapIndex idx3dCaps, uint32_t *pu32Val)
3510{
3511 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
3512 AssertReturn(pState, VERR_INVALID_STATE);
3513
3514 int rc = VINF_SUCCESS;
3515
3516 *pu32Val = 0;
3517
3518 if (idx3dCaps > SVGA3D_DEVCAP_MAX)
3519 {
3520 LogRelMax(16, ("VMSVGA: unsupported SVGA3D_DEVCAP %d\n", idx3dCaps));
3521 return VERR_NOT_SUPPORTED;
3522 }
3523
3524 D3D_FEATURE_LEVEL const FeatureLevel = pState->pBackend->dxDevice.FeatureLevel;
3525
3526 /* Most values are taken from:
3527 * https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-intro
3528 *
3529 * Shader values are from
3530 * https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-models
3531 */
3532
3533 switch (idx3dCaps)
3534 {
3535 case SVGA3D_DEVCAP_3D:
3536 *pu32Val = 1;
3537 break;
3538
3539 case SVGA3D_DEVCAP_MAX_LIGHTS:
3540 *pu32Val = SVGA3D_NUM_LIGHTS; /* VGPU9. Not applicable to DX11. */
3541 break;
3542
3543 case SVGA3D_DEVCAP_MAX_TEXTURES:
3544 *pu32Val = SVGA3D_NUM_TEXTURE_UNITS; /* VGPU9. Not applicable to DX11. */
3545 break;
3546
3547 case SVGA3D_DEVCAP_MAX_CLIP_PLANES:
3548 *pu32Val = SVGA3D_NUM_CLIPPLANES;
3549 break;
3550
3551 case SVGA3D_DEVCAP_VERTEX_SHADER_VERSION:
3552 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3553 *pu32Val = SVGA3DVSVERSION_40;
3554 else
3555 *pu32Val = SVGA3DVSVERSION_30;
3556 break;
3557
3558 case SVGA3D_DEVCAP_VERTEX_SHADER:
3559 *pu32Val = 1;
3560 break;
3561
3562 case SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION:
3563 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3564 *pu32Val = SVGA3DPSVERSION_40;
3565 else
3566 *pu32Val = SVGA3DPSVERSION_30;
3567 break;
3568
3569 case SVGA3D_DEVCAP_FRAGMENT_SHADER:
3570 *pu32Val = 1;
3571 break;
3572
3573 case SVGA3D_DEVCAP_MAX_RENDER_TARGETS:
3574 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3575 *pu32Val = 8;
3576 else
3577 *pu32Val = 4;
3578 break;
3579
3580 case SVGA3D_DEVCAP_S23E8_TEXTURES:
3581 case SVGA3D_DEVCAP_S10E5_TEXTURES:
3582 /* Must be obsolete by now; surface format caps specify the same thing. */
3583 break;
3584
3585 case SVGA3D_DEVCAP_MAX_FIXED_VERTEXBLEND:
3586 /* Obsolete */
3587 break;
3588
3589 /*
3590 * 2. The BUFFER_FORMAT capabilities are deprecated, and they always
3591 * return TRUE. Even on physical hardware that does not support
3592 * these formats natively, the SVGA3D device will provide an emulation
3593 * which should be invisible to the guest OS.
3594 */
3595 case SVGA3D_DEVCAP_D16_BUFFER_FORMAT:
3596 case SVGA3D_DEVCAP_D24S8_BUFFER_FORMAT:
3597 case SVGA3D_DEVCAP_D24X8_BUFFER_FORMAT:
3598 *pu32Val = 1;
3599 break;
3600
3601 case SVGA3D_DEVCAP_QUERY_TYPES:
3602 /* Obsolete */
3603 break;
3604
3605 case SVGA3D_DEVCAP_TEXTURE_GRADIENT_SAMPLING:
3606 /* Obsolete */
3607 break;
3608
3609 case SVGA3D_DEVCAP_MAX_POINT_SIZE:
3610 AssertCompile(sizeof(uint32_t) == sizeof(float));
3611 *(float *)pu32Val = 256.0f; /* VGPU9. Not applicable to DX11. */
3612 break;
3613
3614 case SVGA3D_DEVCAP_MAX_SHADER_TEXTURES:
3615 /* Obsolete */
3616 break;
3617
3618 case SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH:
3619 case SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT:
3620 if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
3621 *pu32Val = 16384;
3622 else if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3623 *pu32Val = 8192;
3624 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_3)
3625 *pu32Val = 4096;
3626 else
3627 *pu32Val = 2048;
3628 break;
3629
3630 case SVGA3D_DEVCAP_MAX_VOLUME_EXTENT:
3631 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3632 *pu32Val = 2048;
3633 else
3634 *pu32Val = 256;
3635 break;
3636
3637 case SVGA3D_DEVCAP_MAX_TEXTURE_REPEAT:
3638 if (FeatureLevel >= D3D_FEATURE_LEVEL_11_0)
3639 *pu32Val = 16384;
3640 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_3)
3641 *pu32Val = 8192;
3642 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
3643 *pu32Val = 2048;
3644 else
3645 *pu32Val = 128;
3646 break;
3647
3648 case SVGA3D_DEVCAP_MAX_TEXTURE_ASPECT_RATIO:
3649 /* Obsolete */
3650 break;
3651
3652 case SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY:
3653 if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
3654 *pu32Val = D3D11_REQ_MAXANISOTROPY;
3655 else
3656 *pu32Val = 2; // D3D_FL9_1_DEFAULT_MAX_ANISOTROPY;
3657 break;
3658
3659 case SVGA3D_DEVCAP_MAX_PRIMITIVE_COUNT:
3660 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3661 *pu32Val = UINT32_MAX;
3662 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
3663 *pu32Val = 1048575; // D3D_FL9_2_IA_PRIMITIVE_MAX_COUNT;
3664 else
3665 *pu32Val = 65535; // D3D_FL9_1_IA_PRIMITIVE_MAX_COUNT;
3666 break;
3667
3668 case SVGA3D_DEVCAP_MAX_VERTEX_INDEX:
3669 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3670 *pu32Val = UINT32_MAX;
3671 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_2)
3672 *pu32Val = 1048575;
3673 else
3674 *pu32Val = 65534;
3675 break;
3676
3677 case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_INSTRUCTIONS:
3678 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3679 *pu32Val = UINT32_MAX;
3680 else
3681 *pu32Val = 512;
3682 break;
3683
3684 case SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_INSTRUCTIONS:
3685 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3686 *pu32Val = UINT32_MAX;
3687 else
3688 *pu32Val = 512;
3689 break;
3690
3691 case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEMPS:
3692 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3693 *pu32Val = 4096;
3694 else
3695 *pu32Val = 32;
3696 break;
3697
3698 case SVGA3D_DEVCAP_MAX_FRAGMENT_SHADER_TEMPS:
3699 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3700 *pu32Val = 4096;
3701 else
3702 *pu32Val = 32;
3703 break;
3704
3705 case SVGA3D_DEVCAP_TEXTURE_OPS:
3706 /* Obsolete */
3707 break;
3708
3709 case SVGA3D_DEVCAP_SURFACEFMT_X8R8G8B8:
3710 case SVGA3D_DEVCAP_SURFACEFMT_A8R8G8B8:
3711 case SVGA3D_DEVCAP_SURFACEFMT_A2R10G10B10:
3712 case SVGA3D_DEVCAP_SURFACEFMT_X1R5G5B5:
3713 case SVGA3D_DEVCAP_SURFACEFMT_A1R5G5B5:
3714 case SVGA3D_DEVCAP_SURFACEFMT_A4R4G4B4:
3715 case SVGA3D_DEVCAP_SURFACEFMT_R5G6B5:
3716 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE16:
3717 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8_ALPHA8:
3718 case SVGA3D_DEVCAP_SURFACEFMT_ALPHA8:
3719 case SVGA3D_DEVCAP_SURFACEFMT_LUMINANCE8:
3720 case SVGA3D_DEVCAP_SURFACEFMT_Z_D16:
3721 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8:
3722 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24X8:
3723 case SVGA3D_DEVCAP_SURFACEFMT_DXT1:
3724 case SVGA3D_DEVCAP_SURFACEFMT_DXT2:
3725 case SVGA3D_DEVCAP_SURFACEFMT_DXT3:
3726 case SVGA3D_DEVCAP_SURFACEFMT_DXT4:
3727 case SVGA3D_DEVCAP_SURFACEFMT_DXT5:
3728 case SVGA3D_DEVCAP_SURFACEFMT_BUMPX8L8V8U8:
3729 case SVGA3D_DEVCAP_SURFACEFMT_A2W10V10U10:
3730 case SVGA3D_DEVCAP_SURFACEFMT_BUMPU8V8:
3731 case SVGA3D_DEVCAP_SURFACEFMT_Q8W8V8U8:
3732 case SVGA3D_DEVCAP_SURFACEFMT_CxV8U8:
3733 case SVGA3D_DEVCAP_SURFACEFMT_R_S10E5:
3734 case SVGA3D_DEVCAP_SURFACEFMT_R_S23E8:
3735 case SVGA3D_DEVCAP_SURFACEFMT_RG_S10E5:
3736 case SVGA3D_DEVCAP_SURFACEFMT_RG_S23E8:
3737 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S10E5:
3738 case SVGA3D_DEVCAP_SURFACEFMT_ARGB_S23E8:
3739 case SVGA3D_DEVCAP_SURFACEFMT_V16U16:
3740 case SVGA3D_DEVCAP_SURFACEFMT_G16R16:
3741 case SVGA3D_DEVCAP_SURFACEFMT_A16B16G16R16:
3742 case SVGA3D_DEVCAP_SURFACEFMT_UYVY:
3743 case SVGA3D_DEVCAP_SURFACEFMT_YUY2:
3744 case SVGA3D_DEVCAP_SURFACEFMT_NV12:
3745 case SVGA3D_DEVCAP_DEAD10: /* SVGA3D_DEVCAP_SURFACEFMT_AYUV */
3746 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF16:
3747 case SVGA3D_DEVCAP_SURFACEFMT_Z_DF24:
3748 case SVGA3D_DEVCAP_SURFACEFMT_Z_D24S8_INT:
3749 case SVGA3D_DEVCAP_SURFACEFMT_ATI1:
3750 case SVGA3D_DEVCAP_SURFACEFMT_ATI2:
3751 case SVGA3D_DEVCAP_SURFACEFMT_YV12:
3752 {
3753 SVGA3dSurfaceFormat const enmFormat = vmsvgaDXDevCapSurfaceFmt2Format(idx3dCaps);
3754 rc = vmsvgaDXCheckFormatSupportPreDX(pState, enmFormat, pu32Val);
3755 break;
3756 }
3757
3758 case SVGA3D_DEVCAP_MISSING62:
3759 /* Unused */
3760 break;
3761
3762 case SVGA3D_DEVCAP_MAX_VERTEX_SHADER_TEXTURES:
3763 /* Obsolete */
3764 break;
3765
3766 case SVGA3D_DEVCAP_MAX_SIMULTANEOUS_RENDER_TARGETS:
3767 if (FeatureLevel >= D3D_FEATURE_LEVEL_10_0)
3768 *pu32Val = 8;
3769 else if (FeatureLevel >= D3D_FEATURE_LEVEL_9_3)
3770 *pu32Val = 4; // D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT
3771 else
3772 *pu32Val = 1; // D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT
3773 break;
3774
3775 case SVGA3D_DEVCAP_DEAD4: /* SVGA3D_DEVCAP_MULTISAMPLE_NONMASKABLESAMPLES */
3776 case SVGA3D_DEVCAP_DEAD5: /* SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES */
3777 *pu32Val = (1 << (2-1)) | (1 << (4-1)) | (1 << (8-1)); /* 2x, 4x, 8x */
3778 break;
3779
3780 case SVGA3D_DEVCAP_DEAD7: /* SVGA3D_DEVCAP_ALPHATOCOVERAGE */
3781 /* Obsolete */
3782 break;
3783
3784 case SVGA3D_DEVCAP_DEAD6: /* SVGA3D_DEVCAP_SUPERSAMPLE */
3785 /* Obsolete */
3786 break;
3787
3788 case SVGA3D_DEVCAP_AUTOGENMIPMAPS:
3789 *pu32Val = 1;
3790 break;
3791
3792 case SVGA3D_DEVCAP_MAX_CONTEXT_IDS:
3793 *pu32Val = SVGA3D_MAX_CONTEXT_IDS;
3794 break;
3795
3796 case SVGA3D_DEVCAP_MAX_SURFACE_IDS:
3797 *pu32Val = SVGA3D_MAX_SURFACE_IDS;
3798 break;
3799
3800 case SVGA3D_DEVCAP_DEAD1:
3801 /* Obsolete */
3802 break;
3803
3804 case SVGA3D_DEVCAP_DEAD8: /* SVGA3D_DEVCAP_VIDEO_DECODE */
3805 /* Obsolete */
3806 break;
3807
3808 case SVGA3D_DEVCAP_DEAD9: /* SVGA3D_DEVCAP_VIDEO_PROCESS */
3809 /* Obsolete */
3810 break;
3811
3812 case SVGA3D_DEVCAP_LINE_AA:
3813 *pu32Val = 1;
3814 break;
3815
3816 case SVGA3D_DEVCAP_LINE_STIPPLE:
3817 *pu32Val = 0; /* DX11 does not seem to support this directly. */
3818 break;
3819
3820 case SVGA3D_DEVCAP_MAX_LINE_WIDTH:
3821 AssertCompile(sizeof(uint32_t) == sizeof(float));
3822 *(float *)pu32Val = 1.0f;
3823 break;
3824
3825 case SVGA3D_DEVCAP_MAX_AA_LINE_WIDTH:
3826 AssertCompile(sizeof(uint32_t) == sizeof(float));
3827 *(float *)pu32Val = 1.0f;
3828 break;
3829
3830 case SVGA3D_DEVCAP_DEAD3: /* Old SVGA3D_DEVCAP_LOGICOPS */
3831 /* Deprecated. */
3832 AssertCompile(SVGA3D_DEVCAP_DEAD3 == 92); /* Newer SVGA headers redefine this. */
3833 break;
3834
3835 case SVGA3D_DEVCAP_TS_COLOR_KEY:
3836 *pu32Val = 0; /* DX11 does not seem to support this directly. */
3837 break;
3838
3839 case SVGA3D_DEVCAP_DEAD2:
3840 break;
3841
3842 case SVGA3D_DEVCAP_DXCONTEXT:
3843 *pu32Val = 1;
3844 break;
3845
3846 case SVGA3D_DEVCAP_DEAD11: /* SVGA3D_DEVCAP_MAX_TEXTURE_ARRAY_SIZE */
3847 *pu32Val = D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
3848 break;
3849
3850 case SVGA3D_DEVCAP_DX_MAX_VERTEXBUFFERS:
3851 *pu32Val = D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT;
3852 break;
3853
3854 case SVGA3D_DEVCAP_DX_MAX_CONSTANT_BUFFERS:
3855 *pu32Val = D3D11_COMMONSHADER_CONSTANT_BUFFER_HW_SLOT_COUNT;
3856 break;
3857
3858 case SVGA3D_DEVCAP_DX_PROVOKING_VERTEX:
3859 *pu32Val = 0; /* boolean */
3860 break;
3861
3862 case SVGA3D_DEVCAP_DXFMT_X8R8G8B8:
3863 case SVGA3D_DEVCAP_DXFMT_A8R8G8B8:
3864 case SVGA3D_DEVCAP_DXFMT_R5G6B5:
3865 case SVGA3D_DEVCAP_DXFMT_X1R5G5B5:
3866 case SVGA3D_DEVCAP_DXFMT_A1R5G5B5:
3867 case SVGA3D_DEVCAP_DXFMT_A4R4G4B4:
3868 case SVGA3D_DEVCAP_DXFMT_Z_D32:
3869 case SVGA3D_DEVCAP_DXFMT_Z_D16:
3870 case SVGA3D_DEVCAP_DXFMT_Z_D24S8:
3871 case SVGA3D_DEVCAP_DXFMT_Z_D15S1:
3872 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8:
3873 case SVGA3D_DEVCAP_DXFMT_LUMINANCE4_ALPHA4:
3874 case SVGA3D_DEVCAP_DXFMT_LUMINANCE16:
3875 case SVGA3D_DEVCAP_DXFMT_LUMINANCE8_ALPHA8:
3876 case SVGA3D_DEVCAP_DXFMT_DXT1:
3877 case SVGA3D_DEVCAP_DXFMT_DXT2:
3878 case SVGA3D_DEVCAP_DXFMT_DXT3:
3879 case SVGA3D_DEVCAP_DXFMT_DXT4:
3880 case SVGA3D_DEVCAP_DXFMT_DXT5:
3881 case SVGA3D_DEVCAP_DXFMT_BUMPU8V8:
3882 case SVGA3D_DEVCAP_DXFMT_BUMPL6V5U5:
3883 case SVGA3D_DEVCAP_DXFMT_BUMPX8L8V8U8:
3884 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD1:
3885 case SVGA3D_DEVCAP_DXFMT_ARGB_S10E5:
3886 case SVGA3D_DEVCAP_DXFMT_ARGB_S23E8:
3887 case SVGA3D_DEVCAP_DXFMT_A2R10G10B10:
3888 case SVGA3D_DEVCAP_DXFMT_V8U8:
3889 case SVGA3D_DEVCAP_DXFMT_Q8W8V8U8:
3890 case SVGA3D_DEVCAP_DXFMT_CxV8U8:
3891 case SVGA3D_DEVCAP_DXFMT_X8L8V8U8:
3892 case SVGA3D_DEVCAP_DXFMT_A2W10V10U10:
3893 case SVGA3D_DEVCAP_DXFMT_ALPHA8:
3894 case SVGA3D_DEVCAP_DXFMT_R_S10E5:
3895 case SVGA3D_DEVCAP_DXFMT_R_S23E8:
3896 case SVGA3D_DEVCAP_DXFMT_RG_S10E5:
3897 case SVGA3D_DEVCAP_DXFMT_RG_S23E8:
3898 case SVGA3D_DEVCAP_DXFMT_BUFFER:
3899 case SVGA3D_DEVCAP_DXFMT_Z_D24X8:
3900 case SVGA3D_DEVCAP_DXFMT_V16U16:
3901 case SVGA3D_DEVCAP_DXFMT_G16R16:
3902 case SVGA3D_DEVCAP_DXFMT_A16B16G16R16:
3903 case SVGA3D_DEVCAP_DXFMT_UYVY:
3904 case SVGA3D_DEVCAP_DXFMT_YUY2:
3905 case SVGA3D_DEVCAP_DXFMT_NV12:
3906 case SVGA3D_DEVCAP_DXFMT_FORMAT_DEAD2: /* SVGA3D_DEVCAP_DXFMT_AYUV */
3907 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_TYPELESS:
3908 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_UINT:
3909 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_SINT:
3910 case SVGA3D_DEVCAP_DXFMT_R32G32B32_TYPELESS:
3911 case SVGA3D_DEVCAP_DXFMT_R32G32B32_FLOAT:
3912 case SVGA3D_DEVCAP_DXFMT_R32G32B32_UINT:
3913 case SVGA3D_DEVCAP_DXFMT_R32G32B32_SINT:
3914 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_TYPELESS:
3915 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UINT:
3916 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SNORM:
3917 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_SINT:
3918 case SVGA3D_DEVCAP_DXFMT_R32G32_TYPELESS:
3919 case SVGA3D_DEVCAP_DXFMT_R32G32_UINT:
3920 case SVGA3D_DEVCAP_DXFMT_R32G32_SINT:
3921 case SVGA3D_DEVCAP_DXFMT_R32G8X24_TYPELESS:
3922 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT_S8X24_UINT:
3923 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT_X8X24:
3924 case SVGA3D_DEVCAP_DXFMT_X32_G8X24_UINT:
3925 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_TYPELESS:
3926 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UINT:
3927 case SVGA3D_DEVCAP_DXFMT_R11G11B10_FLOAT:
3928 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_TYPELESS:
3929 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM:
3930 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UNORM_SRGB:
3931 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_UINT:
3932 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SINT:
3933 case SVGA3D_DEVCAP_DXFMT_R16G16_TYPELESS:
3934 case SVGA3D_DEVCAP_DXFMT_R16G16_UINT:
3935 case SVGA3D_DEVCAP_DXFMT_R16G16_SINT:
3936 case SVGA3D_DEVCAP_DXFMT_R32_TYPELESS:
3937 case SVGA3D_DEVCAP_DXFMT_D32_FLOAT:
3938 case SVGA3D_DEVCAP_DXFMT_R32_UINT:
3939 case SVGA3D_DEVCAP_DXFMT_R32_SINT:
3940 case SVGA3D_DEVCAP_DXFMT_R24G8_TYPELESS:
3941 case SVGA3D_DEVCAP_DXFMT_D24_UNORM_S8_UINT:
3942 case SVGA3D_DEVCAP_DXFMT_R24_UNORM_X8:
3943 case SVGA3D_DEVCAP_DXFMT_X24_G8_UINT:
3944 case SVGA3D_DEVCAP_DXFMT_R8G8_TYPELESS:
3945 case SVGA3D_DEVCAP_DXFMT_R8G8_UNORM:
3946 case SVGA3D_DEVCAP_DXFMT_R8G8_UINT:
3947 case SVGA3D_DEVCAP_DXFMT_R8G8_SINT:
3948 case SVGA3D_DEVCAP_DXFMT_R16_TYPELESS:
3949 case SVGA3D_DEVCAP_DXFMT_R16_UNORM:
3950 case SVGA3D_DEVCAP_DXFMT_R16_UINT:
3951 case SVGA3D_DEVCAP_DXFMT_R16_SNORM:
3952 case SVGA3D_DEVCAP_DXFMT_R16_SINT:
3953 case SVGA3D_DEVCAP_DXFMT_R8_TYPELESS:
3954 case SVGA3D_DEVCAP_DXFMT_R8_UNORM:
3955 case SVGA3D_DEVCAP_DXFMT_R8_UINT:
3956 case SVGA3D_DEVCAP_DXFMT_R8_SNORM:
3957 case SVGA3D_DEVCAP_DXFMT_R8_SINT:
3958 case SVGA3D_DEVCAP_DXFMT_P8:
3959 case SVGA3D_DEVCAP_DXFMT_R9G9B9E5_SHAREDEXP:
3960 case SVGA3D_DEVCAP_DXFMT_R8G8_B8G8_UNORM:
3961 case SVGA3D_DEVCAP_DXFMT_G8R8_G8B8_UNORM:
3962 case SVGA3D_DEVCAP_DXFMT_BC1_TYPELESS:
3963 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM_SRGB:
3964 case SVGA3D_DEVCAP_DXFMT_BC2_TYPELESS:
3965 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM_SRGB:
3966 case SVGA3D_DEVCAP_DXFMT_BC3_TYPELESS:
3967 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM_SRGB:
3968 case SVGA3D_DEVCAP_DXFMT_BC4_TYPELESS:
3969 case SVGA3D_DEVCAP_DXFMT_ATI1:
3970 case SVGA3D_DEVCAP_DXFMT_BC4_SNORM:
3971 case SVGA3D_DEVCAP_DXFMT_BC5_TYPELESS:
3972 case SVGA3D_DEVCAP_DXFMT_ATI2:
3973 case SVGA3D_DEVCAP_DXFMT_BC5_SNORM:
3974 case SVGA3D_DEVCAP_DXFMT_R10G10B10_XR_BIAS_A2_UNORM:
3975 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_TYPELESS:
3976 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM_SRGB:
3977 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_TYPELESS:
3978 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM_SRGB:
3979 case SVGA3D_DEVCAP_DXFMT_Z_DF16:
3980 case SVGA3D_DEVCAP_DXFMT_Z_DF24:
3981 case SVGA3D_DEVCAP_DXFMT_Z_D24S8_INT:
3982 case SVGA3D_DEVCAP_DXFMT_YV12:
3983 case SVGA3D_DEVCAP_DXFMT_R32G32B32A32_FLOAT:
3984 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_FLOAT:
3985 case SVGA3D_DEVCAP_DXFMT_R16G16B16A16_UNORM:
3986 case SVGA3D_DEVCAP_DXFMT_R32G32_FLOAT:
3987 case SVGA3D_DEVCAP_DXFMT_R10G10B10A2_UNORM:
3988 case SVGA3D_DEVCAP_DXFMT_R8G8B8A8_SNORM:
3989 case SVGA3D_DEVCAP_DXFMT_R16G16_FLOAT:
3990 case SVGA3D_DEVCAP_DXFMT_R16G16_UNORM:
3991 case SVGA3D_DEVCAP_DXFMT_R16G16_SNORM:
3992 case SVGA3D_DEVCAP_DXFMT_R32_FLOAT:
3993 case SVGA3D_DEVCAP_DXFMT_R8G8_SNORM:
3994 case SVGA3D_DEVCAP_DXFMT_R16_FLOAT:
3995 case SVGA3D_DEVCAP_DXFMT_D16_UNORM:
3996 case SVGA3D_DEVCAP_DXFMT_A8_UNORM:
3997 case SVGA3D_DEVCAP_DXFMT_BC1_UNORM:
3998 case SVGA3D_DEVCAP_DXFMT_BC2_UNORM:
3999 case SVGA3D_DEVCAP_DXFMT_BC3_UNORM:
4000 case SVGA3D_DEVCAP_DXFMT_B5G6R5_UNORM:
4001 case SVGA3D_DEVCAP_DXFMT_B5G5R5A1_UNORM:
4002 case SVGA3D_DEVCAP_DXFMT_B8G8R8A8_UNORM:
4003 case SVGA3D_DEVCAP_DXFMT_B8G8R8X8_UNORM:
4004 case SVGA3D_DEVCAP_DXFMT_BC4_UNORM:
4005 case SVGA3D_DEVCAP_DXFMT_BC5_UNORM:
4006 case SVGA3D_DEVCAP_DXFMT_BC6H_TYPELESS:
4007 case SVGA3D_DEVCAP_DXFMT_BC6H_UF16:
4008 case SVGA3D_DEVCAP_DXFMT_BC6H_SF16:
4009 case SVGA3D_DEVCAP_DXFMT_BC7_TYPELESS:
4010 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM:
4011 case SVGA3D_DEVCAP_DXFMT_BC7_UNORM_SRGB:
4012 {
4013 SVGA3dSurfaceFormat const enmFormat = vmsvgaDXDevCapDxfmt2Format(idx3dCaps);
4014 rc = vmsvgaDXCheckFormatSupport(pState, enmFormat, pu32Val);
4015 break;
4016 }
4017
4018 case SVGA3D_DEVCAP_SM41:
4019 *pu32Val = 0; /* boolean */
4020 break;
4021
4022 case SVGA3D_DEVCAP_MULTISAMPLE_2X:
4023 *pu32Val = 0; /* boolean */
4024 break;
4025
4026 case SVGA3D_DEVCAP_MULTISAMPLE_4X:
4027 *pu32Val = 0; /* boolean */
4028 break;
4029
4030 case SVGA3D_DEVCAP_MS_FULL_QUALITY:
4031 *pu32Val = 0; /* boolean */
4032 break;
4033
4034 case SVGA3D_DEVCAP_LOGICOPS:
4035 AssertCompile(SVGA3D_DEVCAP_LOGICOPS == 248);
4036 *pu32Val = 0; /* boolean */
4037 break;
4038
4039 case SVGA3D_DEVCAP_LOGIC_BLENDOPS:
4040 *pu32Val = 0; /* boolean */
4041 break;
4042
4043 case SVGA3D_DEVCAP_RESERVED_1:
4044 break;
4045
4046 case SVGA3D_DEVCAP_RESERVED_2:
4047 break;
4048
4049 case SVGA3D_DEVCAP_SM5:
4050 *pu32Val = 0; /* boolean */
4051 break;
4052
4053 case SVGA3D_DEVCAP_MULTISAMPLE_8X:
4054 *pu32Val = 0; /* boolean */
4055 break;
4056
4057 case SVGA3D_DEVCAP_MAX:
4058 case SVGA3D_DEVCAP_INVALID:
4059 rc = VERR_NOT_SUPPORTED;
4060 break;
4061 }
4062
4063 return rc;
4064}
4065
4066
4067static DECLCALLBACK(int) vmsvga3dBackChangeMode(PVGASTATECC pThisCC)
4068{
4069 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4070 AssertReturn(pState, VERR_INVALID_STATE);
4071
4072 return VINF_SUCCESS;
4073}
4074
4075
4076static DECLCALLBACK(int) vmsvga3dBackSurfaceCopy(PVGASTATECC pThisCC, SVGA3dSurfaceImageId dest, SVGA3dSurfaceImageId src,
4077 uint32_t cCopyBoxes, SVGA3dCopyBox *pBox)
4078{
4079 RT_NOREF(cCopyBoxes, pBox);
4080
4081 LogFunc(("src sid %d -> dst sid %d\n", src.sid, dest.sid));
4082
4083 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4084 AssertReturn(pState, VERR_INVALID_STATE);
4085
4086 PVMSVGA3DBACKEND pBackend = pState->pBackend;
4087
4088 PVMSVGA3DSURFACE pSrcSurface;
4089 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, src.sid, &pSrcSurface);
4090 AssertRCReturn(rc, rc);
4091
4092 PVMSVGA3DSURFACE pDstSurface;
4093 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, dest.sid, &pDstSurface);
4094 AssertRCReturn(rc, rc);
4095
4096 LogFunc(("src%s cid %d -> dst%s cid %d\n",
4097 pSrcSurface->pBackendSurface ? "" : " sysmem",
4098 pSrcSurface ? pSrcSurface->idAssociatedContext : SVGA_ID_INVALID,
4099 pDstSurface->pBackendSurface ? "" : " sysmem",
4100 pDstSurface ? pDstSurface->idAssociatedContext : SVGA_ID_INVALID));
4101
4102 //DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
4103 //AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
4104
4105 if (pSrcSurface->pBackendSurface)
4106 {
4107 if (pDstSurface->pBackendSurface == NULL)
4108 {
4109 /* Create the target if it can be used as a device context shared resource (render or screen target). */
4110 if (pBackend->fSingleDevice || dxIsSurfaceShareable(pDstSurface))
4111 {
4112 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, NULL, pDstSurface);
4113 AssertRCReturn(rc, rc);
4114 }
4115 }
4116
4117 if (pDstSurface->pBackendSurface)
4118 {
4119 /* Surface -> Surface. */
4120 /* Expect both of them to be shared surfaces created by the backend context. */
4121 Assert(pSrcSurface->idAssociatedContext == DX_CID_BACKEND && pDstSurface->idAssociatedContext == DX_CID_BACKEND);
4122
4123 /* Wait for the source surface to finish drawing. */
4124 dxSurfaceWait(pState, pSrcSurface, DX_CID_BACKEND);
4125
4126 DXDEVICE *pDXDevice = &pBackend->dxDevice;
4127
4128 /* Clip the box. */
4129 PVMSVGA3DMIPMAPLEVEL pSrcMipLevel;
4130 rc = vmsvga3dMipmapLevel(pSrcSurface, src.face, src.mipmap, &pSrcMipLevel);
4131 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
4132
4133 PVMSVGA3DMIPMAPLEVEL pDstMipLevel;
4134 rc = vmsvga3dMipmapLevel(pDstSurface, dest.face, dest.mipmap, &pDstMipLevel);
4135 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
4136
4137 SVGA3dCopyBox clipBox = *pBox;
4138 vmsvgaR3ClipCopyBox(&pSrcMipLevel->mipmapSize, &pDstMipLevel->mipmapSize, &clipBox);
4139
4140 UINT DstSubresource = vmsvga3dCalcSubresource(dest.mipmap, dest.face, pDstSurface->cLevels);
4141 UINT DstX = clipBox.x;
4142 UINT DstY = clipBox.y;
4143 UINT DstZ = clipBox.z;
4144
4145 UINT SrcSubresource = vmsvga3dCalcSubresource(src.mipmap, src.face, pSrcSurface->cLevels);
4146 D3D11_BOX SrcBox;
4147 SrcBox.left = clipBox.srcx;
4148 SrcBox.top = clipBox.srcy;
4149 SrcBox.front = clipBox.srcz;
4150 SrcBox.right = clipBox.srcx + clipBox.w;
4151 SrcBox.bottom = clipBox.srcy + clipBox.h;
4152 SrcBox.back = clipBox.srcz + clipBox.d;
4153
4154 Assert(cCopyBoxes == 1); /** @todo */
4155
4156 ID3D11Resource *pDstResource;
4157 ID3D11Resource *pSrcResource;
4158 pDstResource = dxResource(pState, pDstSurface, NULL);
4159 pSrcResource = dxResource(pState, pSrcSurface, NULL);
4160
4161 pDXDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
4162 pSrcResource, SrcSubresource, &SrcBox);
4163
4164 pDstSurface->pBackendSurface->cidDrawing = DX_CID_BACKEND;
4165 }
4166 else
4167 {
4168 /* Surface -> Memory. */
4169 AssertFailed(); /** @todo implement */
4170 }
4171 }
4172 else
4173 {
4174 /* Memory -> Surface. */
4175 AssertFailed(); /** @todo implement */
4176 }
4177
4178 return rc;
4179}
4180
4181
4182static DECLCALLBACK(void) vmsvga3dBackUpdateHostScreenViewport(PVGASTATECC pThisCC, uint32_t idScreen, VMSVGAVIEWPORT const *pOldViewport)
4183{
4184 RT_NOREF(pThisCC, idScreen, pOldViewport);
4185 /** @todo Scroll the screen content without requiring the guest to redraw. */
4186}
4187
4188
4189static DECLCALLBACK(int) vmsvga3dBackSurfaceUpdateHeapBuffers(PVGASTATECC pThisCC, PVMSVGA3DSURFACE pSurface)
4190{
4191 /** @todo */
4192 RT_NOREF(pThisCC, pSurface);
4193 return VERR_NOT_IMPLEMENTED;
4194}
4195
4196
4197#if 0 /*unused*/
4198/**
4199 * Create a new 3d context
4200 *
4201 * @returns VBox status code.
4202 * @param pThisCC The VGA/VMSVGA state for ring-3.
4203 * @param cid Context id
4204 */
4205static DECLCALLBACK(int) vmsvga3dBackContextDefine(PVGASTATECC pThisCC, uint32_t cid)
4206{
4207 RT_NOREF(cid);
4208
4209 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4210 AssertReturn(pState, VERR_INVALID_STATE);
4211
4212 AssertFailed();
4213 return VERR_NOT_IMPLEMENTED;
4214}
4215
4216
4217/**
4218 * Destroy an existing 3d context
4219 *
4220 * @returns VBox status code.
4221 * @param pThisCC The VGA/VMSVGA state for ring-3.
4222 * @param cid Context id
4223 */
4224static DECLCALLBACK(int) vmsvga3dBackContextDestroy(PVGASTATECC pThisCC, uint32_t cid)
4225{
4226 RT_NOREF(cid);
4227
4228 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4229 AssertReturn(pState, VERR_INVALID_STATE);
4230
4231 AssertFailed();
4232 return VINF_SUCCESS;
4233}
4234
4235
4236static DECLCALLBACK(int) vmsvga3dBackSetTransform(PVGASTATECC pThisCC, uint32_t cid, SVGA3dTransformType type, float matrix[16])
4237{
4238 RT_NOREF(cid, type, matrix);
4239
4240 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4241 AssertReturn(pState, VERR_INVALID_STATE);
4242
4243 AssertFailed();
4244 return VINF_SUCCESS;
4245}
4246
4247
4248static DECLCALLBACK(int) vmsvga3dBackSetZRange(PVGASTATECC pThisCC, uint32_t cid, SVGA3dZRange zRange)
4249{
4250 RT_NOREF(cid, zRange);
4251
4252 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4253 AssertReturn(pState, VERR_INVALID_STATE);
4254
4255 AssertFailed();
4256 return VINF_SUCCESS;
4257}
4258
4259
4260static DECLCALLBACK(int) vmsvga3dBackSetRenderState(PVGASTATECC pThisCC, uint32_t cid, uint32_t cRenderStates, SVGA3dRenderState *pRenderState)
4261{
4262 RT_NOREF(cid, cRenderStates, pRenderState);
4263
4264 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4265 AssertReturn(pState, VERR_INVALID_STATE);
4266
4267 AssertFailed();
4268 return VINF_SUCCESS;
4269}
4270
4271
4272static DECLCALLBACK(int) vmsvga3dBackSetRenderTarget(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRenderTargetType type, SVGA3dSurfaceImageId target)
4273{
4274 RT_NOREF(cid, type, target);
4275
4276 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4277 AssertReturn(pState, VERR_INVALID_STATE);
4278
4279 AssertFailed();
4280 return VINF_SUCCESS;
4281}
4282
4283
4284static DECLCALLBACK(int) vmsvga3dBackSetTextureState(PVGASTATECC pThisCC, uint32_t cid, uint32_t cTextureStates, SVGA3dTextureState *pTextureState)
4285{
4286 RT_NOREF(cid, cTextureStates, pTextureState);
4287
4288 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4289 AssertReturn(pState, VERR_INVALID_STATE);
4290
4291 AssertFailed();
4292 return VINF_SUCCESS;
4293}
4294
4295
4296static DECLCALLBACK(int) vmsvga3dBackSetMaterial(PVGASTATECC pThisCC, uint32_t cid, SVGA3dFace face, SVGA3dMaterial *pMaterial)
4297{
4298 RT_NOREF(cid, face, pMaterial);
4299
4300 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4301 AssertReturn(pState, VERR_INVALID_STATE);
4302
4303 AssertFailed();
4304 return VINF_SUCCESS;
4305}
4306
4307
4308static DECLCALLBACK(int) vmsvga3dBackSetLightData(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, SVGA3dLightData *pData)
4309{
4310 RT_NOREF(cid, index, pData);
4311
4312 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4313 AssertReturn(pState, VERR_INVALID_STATE);
4314
4315 AssertFailed();
4316 return VINF_SUCCESS;
4317}
4318
4319
4320static DECLCALLBACK(int) vmsvga3dBackSetLightEnabled(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, uint32_t enabled)
4321{
4322 RT_NOREF(cid, index, enabled);
4323
4324 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4325 AssertReturn(pState, VERR_INVALID_STATE);
4326
4327 AssertFailed();
4328 return VINF_SUCCESS;
4329}
4330
4331
4332static DECLCALLBACK(int) vmsvga3dBackSetViewPort(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRect *pRect)
4333{
4334 RT_NOREF(cid, pRect);
4335
4336 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4337 AssertReturn(pState, VERR_INVALID_STATE);
4338
4339 AssertFailed();
4340 return VINF_SUCCESS;
4341}
4342
4343
4344static DECLCALLBACK(int) vmsvga3dBackSetClipPlane(PVGASTATECC pThisCC, uint32_t cid, uint32_t index, float plane[4])
4345{
4346 RT_NOREF(cid, index, plane);
4347
4348 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4349 AssertReturn(pState, VERR_INVALID_STATE);
4350
4351 AssertFailed();
4352 return VINF_SUCCESS;
4353}
4354
4355
4356static DECLCALLBACK(int) vmsvga3dBackCommandClear(PVGASTATECC pThisCC, uint32_t cid, SVGA3dClearFlag clearFlag, uint32_t color, float depth,
4357 uint32_t stencil, uint32_t cRects, SVGA3dRect *pRect)
4358{
4359 /* From SVGA3D_BeginClear comments:
4360 *
4361 * Clear is not affected by clipping, depth test, or other
4362 * render state which affects the fragment pipeline.
4363 *
4364 * Therefore this code must ignore the current scissor rect.
4365 */
4366
4367 RT_NOREF(cid, clearFlag, color, depth, stencil, cRects, pRect);
4368
4369 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4370 AssertReturn(pState, VERR_INVALID_STATE);
4371
4372 AssertFailed();
4373 return VINF_SUCCESS;
4374}
4375
4376
4377static DECLCALLBACK(int) vmsvga3dBackDrawPrimitives(PVGASTATECC pThisCC, uint32_t cid, uint32_t numVertexDecls, SVGA3dVertexDecl *pVertexDecl,
4378 uint32_t numRanges, SVGA3dPrimitiveRange *pRange,
4379 uint32_t cVertexDivisor, SVGA3dVertexDivisor *pVertexDivisor)
4380{
4381 RT_NOREF(cid, numVertexDecls, pVertexDecl, numRanges, pRange, cVertexDivisor, pVertexDivisor);
4382
4383 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4384 AssertReturn(pState, VERR_INVALID_STATE);
4385
4386 AssertFailed();
4387 return VINF_SUCCESS;
4388}
4389
4390
4391static DECLCALLBACK(int) vmsvga3dBackSetScissorRect(PVGASTATECC pThisCC, uint32_t cid, SVGA3dRect *pRect)
4392{
4393 RT_NOREF(cid, pRect);
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) vmsvga3dBackGenerateMipmaps(PVGASTATECC pThisCC, uint32_t sid, SVGA3dTextureFilter filter)
4404{
4405 RT_NOREF(sid, filter);
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) vmsvga3dBackShaderDefine(PVGASTATECC pThisCC, uint32_t cid, uint32_t shid, SVGA3dShaderType type,
4416 uint32_t cbData, uint32_t *pShaderData)
4417{
4418 RT_NOREF(cid, shid, type, cbData, pShaderData);
4419
4420 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4421 AssertReturn(pState, VERR_INVALID_STATE);
4422
4423 AssertFailed();
4424 return VINF_SUCCESS;
4425}
4426
4427
4428static DECLCALLBACK(int) vmsvga3dBackShaderDestroy(PVGASTATECC pThisCC, uint32_t cid, uint32_t shid, SVGA3dShaderType type)
4429{
4430 RT_NOREF(cid, shid, type);
4431
4432 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4433 AssertReturn(pState, VERR_INVALID_STATE);
4434
4435 AssertFailed();
4436 return VINF_SUCCESS;
4437}
4438
4439
4440static DECLCALLBACK(int) vmsvga3dBackShaderSet(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext, uint32_t cid, SVGA3dShaderType type, uint32_t shid)
4441{
4442 RT_NOREF(pContext, cid, type, shid);
4443
4444 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4445 AssertReturn(pState, VERR_INVALID_STATE);
4446
4447 AssertFailed();
4448 return VINF_SUCCESS;
4449}
4450
4451
4452static DECLCALLBACK(int) vmsvga3dBackShaderSetConst(PVGASTATECC pThisCC, uint32_t cid, uint32_t reg, SVGA3dShaderType type,
4453 SVGA3dShaderConstType ctype, uint32_t cRegisters, uint32_t *pValues)
4454{
4455 RT_NOREF(cid, reg, type, ctype, cRegisters, pValues);
4456
4457 PVMSVGA3DSTATE pState = pThisCC->svga.p3dState;
4458 AssertReturn(pState, VERR_INVALID_STATE);
4459
4460 AssertFailed();
4461 return VINF_SUCCESS;
4462}
4463#endif
4464
4465
4466/**
4467 * Destroy backend specific surface bits (part of SVGA_3D_CMD_SURFACE_DESTROY).
4468 *
4469 * @param pThisCC The device context.
4470 * @param pSurface The surface being destroyed.
4471 */
4472static DECLCALLBACK(void) vmsvga3dBackSurfaceDestroy(PVGASTATECC pThisCC, PVMSVGA3DSURFACE pSurface)
4473{
4474 RT_NOREF(pThisCC);
4475
4476 /* The caller should not use the function for system memory surfaces. */
4477 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
4478 if (!pBackendSurface)
4479 return;
4480 pSurface->pBackendSurface = NULL;
4481
4482 LogFunc(("sid=%u\n", pSurface->id));
4483
4484 /* If any views have been created for this resource, then also release them. */
4485 DXVIEW *pIter, *pNext;
4486 RTListForEachSafe(&pBackendSurface->u2.Texture.listView, pIter, pNext, DXVIEW, nodeSurfaceView)
4487 {
4488 LogFunc(("pIter=%p, pNext=%p\n", pIter, pNext));
4489 dxViewDestroy(pIter);
4490 }
4491
4492 if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET
4493 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_1D
4494 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
4495 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_CUBE
4496 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
4497 {
4498 D3D_RELEASE(pBackendSurface->staging.pResource);
4499 D3D_RELEASE(pBackendSurface->dynamic.pResource);
4500 D3D_RELEASE(pBackendSurface->u.pResource);
4501 }
4502 else if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
4503 {
4504 D3D_RELEASE(pBackendSurface->u.pBuffer);
4505 }
4506 else
4507 {
4508 AssertFailed();
4509 }
4510
4511 RTMemFree(pBackendSurface);
4512
4513 /* No context has created the surface, because the surface does not exist anymore. */
4514 pSurface->idAssociatedContext = SVGA_ID_INVALID;
4515}
4516
4517
4518static DECLCALLBACK(void) vmsvga3dBackSurfaceInvalidateImage(PVGASTATECC pThisCC, PVMSVGA3DSURFACE pSurface, uint32_t uFace, uint32_t uMipmap)
4519{
4520 RT_NOREF(pThisCC, uFace, uMipmap);
4521
4522 /* The caller should not use the function for system memory surfaces. */
4523 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
4524 if (!pBackendSurface)
4525 return;
4526
4527 LogFunc(("sid=%u\n", pSurface->id));
4528
4529 /* The guest uses this to invalidate a buffer. */
4530 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_BUFFER)
4531 {
4532 Assert(uFace == 0 && uMipmap == 0); /* The caller ensures this. */
4533 /** @todo This causes flickering when a buffer is invalidated and re-created right before a draw call. */
4534 //vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
4535 }
4536 else
4537 {
4538 /** @todo Delete views that have been created for this mipmap.
4539 * For now just delete all views, they will be recte=reated if necessary.
4540 */
4541 ASSERT_GUEST_FAILED();
4542 DXVIEW *pIter, *pNext;
4543 RTListForEachSafe(&pBackendSurface->u2.Texture.listView, pIter, pNext, DXVIEW, nodeSurfaceView)
4544 {
4545 dxViewDestroy(pIter);
4546 }
4547 }
4548}
4549
4550
4551/**
4552 * Backend worker for implementing SVGA_3D_CMD_SURFACE_STRETCHBLT.
4553 *
4554 * @returns VBox status code.
4555 * @param pThis The VGA device instance.
4556 * @param pState The VMSVGA3d state.
4557 * @param pDstSurface The destination host surface.
4558 * @param uDstFace The destination face (valid).
4559 * @param uDstMipmap The destination mipmap level (valid).
4560 * @param pDstBox The destination box.
4561 * @param pSrcSurface The source host surface.
4562 * @param uSrcFace The destination face (valid).
4563 * @param uSrcMipmap The source mimap level (valid).
4564 * @param pSrcBox The source box.
4565 * @param enmMode The strecht blt mode .
4566 * @param pContext The VMSVGA3d context (already current for OGL).
4567 */
4568static DECLCALLBACK(int) vmsvga3dBackSurfaceStretchBlt(PVGASTATE pThis, PVMSVGA3DSTATE pState,
4569 PVMSVGA3DSURFACE pDstSurface, uint32_t uDstFace, uint32_t uDstMipmap, SVGA3dBox const *pDstBox,
4570 PVMSVGA3DSURFACE pSrcSurface, uint32_t uSrcFace, uint32_t uSrcMipmap, SVGA3dBox const *pSrcBox,
4571 SVGA3dStretchBltMode enmMode, PVMSVGA3DCONTEXT pContext)
4572{
4573 RT_NOREF(pThis, pState, pDstSurface, uDstFace, uDstMipmap, pDstBox,
4574 pSrcSurface, uSrcFace, uSrcMipmap, pSrcBox, enmMode, pContext);
4575
4576 AssertFailed();
4577 return VINF_SUCCESS;
4578}
4579
4580
4581/**
4582 * Backend worker for implementing SVGA_3D_CMD_SURFACE_DMA that copies one box.
4583 *
4584 * @returns Failure status code or @a rc.
4585 * @param pThis The shared VGA/VMSVGA instance data.
4586 * @param pThisCC The VGA/VMSVGA state for ring-3.
4587 * @param pState The VMSVGA3d state.
4588 * @param pSurface The host surface.
4589 * @param pMipLevel Mipmap level. The caller knows it already.
4590 * @param uHostFace The host face (valid).
4591 * @param uHostMipmap The host mipmap level (valid).
4592 * @param GuestPtr The guest pointer.
4593 * @param cbGuestPitch The guest pitch.
4594 * @param transfer The transfer direction.
4595 * @param pBox The box to copy (clipped, valid, except for guest's srcx, srcy, srcz).
4596 * @param pContext The context (for OpenGL).
4597 * @param rc The current rc for all boxes.
4598 * @param iBox The current box number (for Direct 3D).
4599 */
4600static DECLCALLBACK(int) vmsvga3dBackSurfaceDMACopyBox(PVGASTATE pThis, PVGASTATECC pThisCC, PVMSVGA3DSTATE pState, PVMSVGA3DSURFACE pSurface,
4601 PVMSVGA3DMIPMAPLEVEL pMipLevel, uint32_t uHostFace, uint32_t uHostMipmap,
4602 SVGAGuestPtr GuestPtr, uint32_t cbGuestPitch, SVGA3dTransferType transfer,
4603 SVGA3dCopyBox const *pBox, PVMSVGA3DCONTEXT pContext, int rc, int iBox)
4604{
4605 RT_NOREF(pState, pMipLevel, pContext, iBox);
4606
4607 /* The called should not use the function for system memory surfaces. */
4608 PVMSVGA3DBACKENDSURFACE pBackendSurface = pSurface->pBackendSurface;
4609 AssertReturn(pBackendSurface, VERR_INVALID_PARAMETER);
4610
4611 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_SCREEN_TARGET)
4612 {
4613 /** @todo This is generic code and should be in DevVGA-SVGA3d.cpp for backends which support Map/Unmap. */
4614 AssertReturn(uHostFace == 0 && uHostMipmap == 0, VERR_INVALID_PARAMETER);
4615
4616 uint32_t const u32GuestBlockX = pBox->srcx / pSurface->cxBlock;
4617 uint32_t const u32GuestBlockY = pBox->srcy / pSurface->cyBlock;
4618 Assert(u32GuestBlockX * pSurface->cxBlock == pBox->srcx);
4619 Assert(u32GuestBlockY * pSurface->cyBlock == pBox->srcy);
4620 uint32_t const cBlocksX = (pBox->w + pSurface->cxBlock - 1) / pSurface->cxBlock;
4621 uint32_t const cBlocksY = (pBox->h + pSurface->cyBlock - 1) / pSurface->cyBlock;
4622 AssertMsgReturn(cBlocksX && cBlocksY, ("Empty box %dx%d\n", pBox->w, pBox->h), VERR_INTERNAL_ERROR);
4623
4624 /* vmsvgaR3GmrTransfer verifies uGuestOffset.
4625 * srcx(u32GuestBlockX) and srcy(u32GuestBlockY) have been verified in vmsvga3dSurfaceDMA
4626 * to not cause 32 bit overflow when multiplied by cbBlock and cbGuestPitch.
4627 */
4628 uint64_t const uGuestOffset = u32GuestBlockX * pSurface->cbBlock + u32GuestBlockY * cbGuestPitch;
4629 AssertReturn(uGuestOffset < UINT32_MAX, VERR_INVALID_PARAMETER);
4630
4631 SVGA3dSurfaceImageId image;
4632 image.sid = pSurface->id;
4633 image.face = uHostFace;
4634 image.mipmap = uHostMipmap;
4635
4636 SVGA3dBox box;
4637 box.x = pBox->x;
4638 box.y = pBox->y;
4639 box.z = 0;
4640 box.w = pBox->w;
4641 box.h = pBox->h;
4642 box.d = 1;
4643
4644 VMSVGA3D_SURFACE_MAP const enmMap = transfer == SVGA3D_WRITE_HOST_VRAM
4645 ? VMSVGA3D_SURFACE_MAP_WRITE
4646 : VMSVGA3D_SURFACE_MAP_READ;
4647
4648 VMSVGA3D_MAPPED_SURFACE map;
4649 rc = vmsvga3dBackSurfaceMap(pThisCC, &image, &box, enmMap, &map);
4650 if (RT_SUCCESS(rc))
4651 {
4652 /* Prepare parameters for vmsvgaR3GmrTransfer, which needs the host buffer address, size
4653 * and offset of the first scanline.
4654 */
4655 uint32_t const cbLockedBuf = map.cbRowPitch * cBlocksY;
4656 uint8_t *pu8LockedBuf = (uint8_t *)map.pvData;
4657 uint32_t const offLockedBuf = 0;
4658
4659 rc = vmsvgaR3GmrTransfer(pThis,
4660 pThisCC,
4661 transfer,
4662 pu8LockedBuf,
4663 cbLockedBuf,
4664 offLockedBuf,
4665 map.cbRowPitch,
4666 GuestPtr,
4667 (uint32_t)uGuestOffset,
4668 cbGuestPitch,
4669 cBlocksX * pSurface->cbBlock,
4670 cBlocksY);
4671 AssertRC(rc);
4672
4673 // Log4(("first line:\n%.*Rhxd\n", cBlocksX * pSurface->cbBlock, LockedRect.pBits));
4674
4675 //vmsvga3dMapWriteBmpFile(&map, "Dynamic");
4676
4677 vmsvga3dBackSurfaceUnmap(pThisCC, &image, &map, /* fWritten = */ true);
4678 }
4679#if 0
4680 //DEBUG_BREAKPOINT_TEST();
4681 rc = vmsvga3dBackSurfaceMap(pThisCC, &image, NULL, VMSVGA3D_SURFACE_MAP_READ, &map);
4682 if (RT_SUCCESS(rc))
4683 {
4684 vmsvga3dMapWriteBmpFile(&map, "Staging");
4685
4686 vmsvga3dBackSurfaceUnmap(pThisCC, &image, &map, /* fWritten = */ false);
4687 }
4688#endif
4689 }
4690 else if ( pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_1D
4691 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_2D
4692 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_CUBE
4693 || pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
4694 {
4695 /** @todo This is generic code and should be in DevVGA-SVGA3d.cpp for backends which support Map/Unmap. */
4696 uint32_t const u32GuestBlockX = pBox->srcx / pSurface->cxBlock;
4697 uint32_t const u32GuestBlockY = pBox->srcy / pSurface->cyBlock;
4698 Assert(u32GuestBlockX * pSurface->cxBlock == pBox->srcx);
4699 Assert(u32GuestBlockY * pSurface->cyBlock == pBox->srcy);
4700 uint32_t const cBlocksX = (pBox->w + pSurface->cxBlock - 1) / pSurface->cxBlock;
4701 uint32_t const cBlocksY = (pBox->h + pSurface->cyBlock - 1) / pSurface->cyBlock;
4702 AssertMsgReturn(cBlocksX && cBlocksY && pBox->d, ("Empty box %dx%dx%d\n", pBox->w, pBox->h, pBox->d), VERR_INTERNAL_ERROR);
4703
4704 /* vmsvgaR3GmrTransfer verifies uGuestOffset.
4705 * srcx(u32GuestBlockX) and srcy(u32GuestBlockY) have been verified in vmsvga3dSurfaceDMA
4706 * to not cause 32 bit overflow when multiplied by cbBlock and cbGuestPitch.
4707 */
4708 uint64_t uGuestOffset = u32GuestBlockX * pSurface->cbBlock + u32GuestBlockY * cbGuestPitch;
4709 AssertReturn(uGuestOffset < UINT32_MAX, VERR_INVALID_PARAMETER);
4710
4711 /* 3D texture needs additional processing. */
4712 ASSERT_GUEST_RETURN( pBox->z < D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
4713 && pBox->d <= D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
4714 && pBox->d <= D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION - pBox->z,
4715 VERR_INVALID_PARAMETER);
4716 ASSERT_GUEST_RETURN( pBox->srcz < D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
4717 && pBox->d <= D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION
4718 && pBox->d <= D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION - pBox->srcz,
4719 VERR_INVALID_PARAMETER);
4720
4721 uGuestOffset += pBox->srcz * pMipLevel->cbSurfacePlane;
4722
4723 SVGA3dSurfaceImageId image;
4724 image.sid = pSurface->id;
4725 image.face = uHostFace;
4726 image.mipmap = uHostMipmap;
4727
4728 SVGA3dBox box;
4729 box.x = pBox->x;
4730 box.y = pBox->y;
4731 box.z = pBox->z;
4732 box.w = pBox->w;
4733 box.h = pBox->h;
4734 box.d = pBox->d;
4735
4736 VMSVGA3D_SURFACE_MAP const enmMap = transfer == SVGA3D_WRITE_HOST_VRAM
4737 ? VMSVGA3D_SURFACE_MAP_WRITE
4738 : VMSVGA3D_SURFACE_MAP_READ;
4739
4740 VMSVGA3D_MAPPED_SURFACE map;
4741 rc = vmsvga3dBackSurfaceMap(pThisCC, &image, &box, enmMap, &map);
4742 if (RT_SUCCESS(rc))
4743 {
4744#if 0
4745 if (box.w == 250 && box.h == 250 && box.d == 1 && enmMap == VMSVGA3D_SURFACE_MAP_READ)
4746 {
4747 DEBUG_BREAKPOINT_TEST();
4748 vmsvga3dMapWriteBmpFile(&map, "P");
4749 }
4750#endif
4751 /* Prepare parameters for vmsvgaR3GmrTransfer, which needs the host buffer address, size
4752 * and offset of the first scanline.
4753 */
4754 uint32_t cbLockedBuf = map.cbRowPitch * cBlocksY;
4755 if (pBackendSurface->enmResType == VMSVGA3D_RESTYPE_TEXTURE_3D)
4756 cbLockedBuf += map.cbDepthPitch * (pBox->d - 1); /// @todo why map does not compute this for 2D textures
4757 uint8_t *pu8LockedBuf = (uint8_t *)map.pvData;
4758 uint32_t offLockedBuf = 0;
4759
4760 for (uint32_t iPlane = 0; iPlane < pBox->d; ++iPlane)
4761 {
4762 AssertBreak(uGuestOffset < UINT32_MAX);
4763
4764 rc = vmsvgaR3GmrTransfer(pThis,
4765 pThisCC,
4766 transfer,
4767 pu8LockedBuf,
4768 cbLockedBuf,
4769 offLockedBuf,
4770 map.cbRowPitch,
4771 GuestPtr,
4772 (uint32_t)uGuestOffset,
4773 cbGuestPitch,
4774 cBlocksX * pSurface->cbBlock,
4775 cBlocksY);
4776 AssertRC(rc);
4777
4778 uGuestOffset += pMipLevel->cbSurfacePlane;
4779 offLockedBuf += map.cbDepthPitch;
4780 }
4781
4782 bool const fWritten = (transfer == SVGA3D_WRITE_HOST_VRAM);
4783 vmsvga3dBackSurfaceUnmap(pThisCC, &image, &map, fWritten);
4784 }
4785 }
4786 else
4787 {
4788 AssertMsgFailed(("Unsupported surface type %d\n", pBackendSurface->enmResType));
4789 rc = VERR_NOT_IMPLEMENTED;
4790 }
4791
4792 return rc;
4793}
4794
4795
4796/**
4797 * Create D3D/OpenGL texture object for the specified surface.
4798 *
4799 * Surfaces are created when needed.
4800 *
4801 * @param pThisCC The device context.
4802 * @param pContext The context.
4803 * @param idAssociatedContext Probably the same as pContext->id.
4804 * @param pSurface The surface to create the texture for.
4805 */
4806static DECLCALLBACK(int) vmsvga3dBackCreateTexture(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext, uint32_t idAssociatedContext,
4807 PVMSVGA3DSURFACE pSurface)
4808
4809{
4810 RT_NOREF(pThisCC, pContext, idAssociatedContext, pSurface);
4811
4812 AssertFailed();
4813 return VINF_SUCCESS;
4814}
4815
4816
4817#if 0 /*unused*/
4818static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryCreate(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
4819{
4820 RT_NOREF(pThisCC, pContext);
4821 AssertFailed();
4822 return VINF_SUCCESS;
4823}
4824
4825
4826static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryBegin(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
4827{
4828 RT_NOREF(pThisCC, pContext);
4829 AssertFailed();
4830 return VINF_SUCCESS;
4831}
4832
4833
4834static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryEnd(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
4835{
4836 RT_NOREF(pThisCC, pContext);
4837 AssertFailed();
4838 return VINF_SUCCESS;
4839}
4840
4841
4842static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryGetData(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext, uint32_t *pu32Pixels)
4843{
4844 RT_NOREF(pThisCC, pContext);
4845 *pu32Pixels = 0;
4846 AssertFailed();
4847 return VINF_SUCCESS;
4848}
4849
4850
4851static DECLCALLBACK(int) vmsvga3dBackOcclusionQueryDelete(PVGASTATECC pThisCC, PVMSVGA3DCONTEXT pContext)
4852{
4853 RT_NOREF(pThisCC, pContext);
4854 AssertFailed();
4855 return VINF_SUCCESS;
4856}
4857#endif
4858
4859
4860/*
4861 * DX callbacks.
4862 */
4863
4864static DECLCALLBACK(int) vmsvga3dBackDXDefineContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
4865{
4866 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
4867
4868 /* Allocate a backend specific context structure. */
4869 PVMSVGA3DBACKENDDXCONTEXT pBackendDXContext = (PVMSVGA3DBACKENDDXCONTEXT)RTMemAllocZ(sizeof(VMSVGA3DBACKENDDXCONTEXT));
4870 AssertPtrReturn(pBackendDXContext, VERR_NO_MEMORY);
4871 pDXContext->pBackendDXContext = pBackendDXContext;
4872
4873 LogFunc(("cid %d\n", pDXContext->cid));
4874
4875 int rc = dxDeviceCreate(pBackend, &pBackendDXContext->dxDevice);
4876 return rc;
4877}
4878
4879
4880static DECLCALLBACK(int) vmsvga3dBackDXDestroyContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
4881{
4882 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
4883
4884 LogFunc(("cid %d\n", pDXContext->cid));
4885
4886 if (pDXContext->pBackendDXContext)
4887 {
4888 /* Clean up context resources. */
4889 VMSVGA3DBACKENDDXCONTEXT *pBackendDXContext = pDXContext->pBackendDXContext;
4890
4891 if (pBackendDXContext->paRenderTargetView)
4892 {
4893 for (uint32_t i = 0; i < pBackendDXContext->cRenderTargetView; ++i)
4894 D3D_RELEASE(pBackendDXContext->paRenderTargetView[i].u.pRenderTargetView);
4895 }
4896 if (pBackendDXContext->paDepthStencilView)
4897 {
4898 for (uint32_t i = 0; i < pBackendDXContext->cDepthStencilView; ++i)
4899 D3D_RELEASE(pBackendDXContext->paDepthStencilView[i].u.pDepthStencilView);
4900 }
4901 if (pBackendDXContext->paShaderResourceView)
4902 {
4903 for (uint32_t i = 0; i < pBackendDXContext->cShaderResourceView; ++i)
4904 D3D_RELEASE(pBackendDXContext->paShaderResourceView[i].u.pShaderResourceView);
4905 }
4906 if (pBackendDXContext->paElementLayout)
4907 {
4908 for (uint32_t i = 0; i < pBackendDXContext->cElementLayout; ++i)
4909 D3D_RELEASE(pBackendDXContext->paElementLayout[i].pElementLayout);
4910 }
4911 if (pBackendDXContext->papBlendState)
4912 DX_RELEASE_ARRAY(pBackendDXContext->cBlendState, pBackendDXContext->papBlendState);
4913 if (pBackendDXContext->papDepthStencilState)
4914 DX_RELEASE_ARRAY(pBackendDXContext->cDepthStencilState, pBackendDXContext->papDepthStencilState);
4915 if (pBackendDXContext->papRasterizerState)
4916 DX_RELEASE_ARRAY(pBackendDXContext->cRasterizerState, pBackendDXContext->papRasterizerState);
4917 if (pBackendDXContext->papSamplerState)
4918 DX_RELEASE_ARRAY(pBackendDXContext->cSamplerState, pBackendDXContext->papSamplerState);
4919 if (pBackendDXContext->paQuery)
4920 {
4921 for (uint32_t i = 0; i < pBackendDXContext->cQuery; ++i)
4922 dxDestroyQuery(&pBackendDXContext->paQuery[i]);
4923 }
4924 if (pBackendDXContext->paShader)
4925 {
4926 for (uint32_t i = 0; i < pBackendDXContext->cShader; ++i)
4927 dxDestroyShader(&pBackendDXContext->paShader[i]);
4928 }
4929 if (pBackendDXContext->paStreamOutput)
4930 {
4931 for (uint32_t i = 0; i < pBackendDXContext->cStreamOutput; ++i)
4932 dxDestroyStreamOutput(&pBackendDXContext->paStreamOutput[i]);
4933 }
4934
4935 RTMemFreeZ(pBackendDXContext->papBlendState, sizeof(pBackendDXContext->papBlendState[0]) * pBackendDXContext->cBlendState);
4936 RTMemFreeZ(pBackendDXContext->papDepthStencilState, sizeof(pBackendDXContext->papDepthStencilState[0]) * pBackendDXContext->cDepthStencilState);
4937 RTMemFreeZ(pBackendDXContext->papSamplerState, sizeof(pBackendDXContext->papSamplerState[0]) * pBackendDXContext->cSamplerState);
4938 RTMemFreeZ(pBackendDXContext->papRasterizerState, sizeof(pBackendDXContext->papRasterizerState[0]) * pBackendDXContext->cRasterizerState);
4939 RTMemFreeZ(pBackendDXContext->paElementLayout, sizeof(pBackendDXContext->paElementLayout[0]) * pBackendDXContext->cElementLayout);
4940 RTMemFreeZ(pBackendDXContext->paRenderTargetView, sizeof(pBackendDXContext->paRenderTargetView[0]) * pBackendDXContext->cRenderTargetView);
4941 RTMemFreeZ(pBackendDXContext->paDepthStencilView, sizeof(pBackendDXContext->paDepthStencilView[0]) * pBackendDXContext->cDepthStencilView);
4942 RTMemFreeZ(pBackendDXContext->paShaderResourceView, sizeof(pBackendDXContext->paShaderResourceView[0]) * pBackendDXContext->cShaderResourceView);
4943 RTMemFreeZ(pBackendDXContext->paQuery, sizeof(pBackendDXContext->paQuery[0]) * pBackendDXContext->cQuery);
4944 RTMemFreeZ(pBackendDXContext->paShader, sizeof(pBackendDXContext->paShader[0]) * pBackendDXContext->cShader);
4945 RTMemFreeZ(pBackendDXContext->paStreamOutput, sizeof(pBackendDXContext->paStreamOutput[0]) * pBackendDXContext->cStreamOutput);
4946
4947 /* Destroy backend surfaces which belong to this context. */
4948 /** @todo The context should have a list of surfaces (and also shared resources). */
4949 for (uint32_t sid = 0; sid < pThisCC->svga.p3dState->cSurfaces; ++sid)
4950 {
4951 PVMSVGA3DSURFACE const pSurface = pThisCC->svga.p3dState->papSurfaces[sid];
4952 if ( pSurface
4953 && pSurface->id == sid)
4954 {
4955 if (pSurface->idAssociatedContext == pDXContext->cid)
4956 {
4957 if (pSurface->pBackendSurface)
4958 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
4959 }
4960 else if (pSurface->idAssociatedContext == DX_CID_BACKEND)
4961 {
4962 /* May have shared resources in this context. */
4963 if (pSurface->pBackendSurface)
4964 {
4965 DXSHAREDTEXTURE *pSharedTexture = (DXSHAREDTEXTURE *)RTAvlU32Get(&pSurface->pBackendSurface->SharedTextureTree, pDXContext->cid);
4966 if (pSharedTexture)
4967 {
4968 Assert(pSharedTexture->sid == sid);
4969 RTAvlU32Remove(&pSurface->pBackendSurface->SharedTextureTree, pDXContext->cid);
4970 D3D_RELEASE(pSharedTexture->pTexture);
4971 RTMemFreeZ(pSharedTexture, sizeof(*pSharedTexture));
4972 }
4973 }
4974 }
4975 }
4976 }
4977
4978 dxDeviceDestroy(pBackend, &pBackendDXContext->dxDevice);
4979
4980 RTMemFreeZ(pBackendDXContext, sizeof(*pBackendDXContext));
4981 pDXContext->pBackendDXContext = NULL;
4982 }
4983 return VINF_SUCCESS;
4984}
4985
4986
4987static DECLCALLBACK(int) vmsvga3dBackDXBindContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
4988{
4989 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
4990 RT_NOREF(pBackend, pDXContext);
4991 return VINF_SUCCESS;
4992}
4993
4994
4995static DECLCALLBACK(int) vmsvga3dBackDXSwitchContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
4996{
4997 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
4998 if (!pBackend->fSingleDevice)
4999 return VINF_NOT_IMPLEMENTED; /* Not required. */
5000
5001 /* The new context state will be applied by the generic DX code. */
5002 RT_NOREF(pDXContext);
5003 return VINF_SUCCESS;
5004}
5005
5006
5007static DECLCALLBACK(int) vmsvga3dBackDXReadbackContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5008{
5009 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5010 RT_NOREF(pBackend, pDXContext);
5011 return VINF_SUCCESS;
5012}
5013
5014
5015static DECLCALLBACK(int) vmsvga3dBackDXInvalidateContext(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5016{
5017 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5018
5019 RT_NOREF(pBackend, pDXContext);
5020 AssertFailed(); /** @todo Implement */
5021 return VERR_NOT_IMPLEMENTED;
5022}
5023
5024
5025static DECLCALLBACK(int) vmsvga3dBackDXSetSingleConstantBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t slot, SVGA3dShaderType type, SVGA3dSurfaceId sid, uint32_t offsetInBytes, uint32_t sizeInBytes)
5026{
5027 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5028 RT_NOREF(pBackend);
5029
5030 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5031 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5032
5033 if (sid == SVGA_ID_INVALID)
5034 {
5035 dxConstantBufferSet(pDevice, slot, type, NULL);
5036 return VINF_SUCCESS;
5037 }
5038
5039 PVMSVGA3DSURFACE pSurface;
5040 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
5041 AssertRCReturn(rc, rc);
5042
5043 PVMSVGA3DMIPMAPLEVEL pMipLevel;
5044 rc = vmsvga3dMipmapLevel(pSurface, 0, 0, &pMipLevel);
5045 AssertRCReturn(rc, rc);
5046
5047 uint32_t const cbSurface = pMipLevel->cbSurface;
5048 ASSERT_GUEST_RETURN( offsetInBytes < cbSurface
5049 && sizeInBytes <= cbSurface - offsetInBytes, VERR_INVALID_PARAMETER);
5050
5051 /* Constant buffers are created on demand. */
5052 Assert(pSurface->pBackendSurface == NULL);
5053
5054 /* Upload the current data, if any. */
5055 D3D11_SUBRESOURCE_DATA *pInitialData = NULL;
5056 D3D11_SUBRESOURCE_DATA initialData;
5057 if (pMipLevel->pSurfaceData)
5058 {
5059 initialData.pSysMem = (uint8_t *)pMipLevel->pSurfaceData + offsetInBytes;
5060 initialData.SysMemPitch = sizeInBytes;
5061 initialData.SysMemSlicePitch = sizeInBytes;
5062
5063 pInitialData = &initialData;
5064
5065 // Log(("%.*Rhxd\n", sizeInBytes, initialData.pSysMem));
5066 }
5067
5068 D3D11_BUFFER_DESC bd;
5069 RT_ZERO(bd);
5070 bd.ByteWidth = sizeInBytes;
5071 bd.Usage = D3D11_USAGE_DEFAULT;
5072 bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
5073 bd.CPUAccessFlags = 0;
5074 bd.MiscFlags = 0;
5075 bd.StructureByteStride = 0;
5076
5077 ID3D11Buffer *pBuffer = 0;
5078 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, pInitialData, &pBuffer);
5079 if (SUCCEEDED(hr))
5080 {
5081 dxConstantBufferSet(pDevice, slot, type, pBuffer);
5082 D3D_RELEASE(pBuffer);
5083 }
5084
5085 return VINF_SUCCESS;
5086}
5087
5088static int dxSetShaderResources(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderType type)
5089{
5090 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5091 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5092
5093//DEBUG_BREAKPOINT_TEST();
5094 AssertReturn(type >= SVGA3D_SHADERTYPE_MIN && type < SVGA3D_SHADERTYPE_MAX, VERR_INVALID_PARAMETER);
5095 uint32_t const idxShaderState = type - SVGA3D_SHADERTYPE_MIN;
5096 uint32_t const *pSRIds = &pDXContext->svgaDXContext.shaderState[idxShaderState].shaderResources[0];
5097 ID3D11ShaderResourceView *papShaderResourceView[SVGA3D_DX_MAX_SRVIEWS];
5098 for (uint32_t i = 0; i < SVGA3D_DX_MAX_SRVIEWS; ++i)
5099 {
5100 SVGA3dShaderResourceViewId shaderResourceViewId = pSRIds[i];
5101 if (shaderResourceViewId != SVGA3D_INVALID_ID)
5102 {
5103 ASSERT_GUEST_RETURN(shaderResourceViewId < pDXContext->pBackendDXContext->cShaderResourceView, VERR_INVALID_PARAMETER);
5104
5105 DXVIEW *pDXView = &pDXContext->pBackendDXContext->paShaderResourceView[shaderResourceViewId];
5106 Assert(pDXView->u.pShaderResourceView);
5107 papShaderResourceView[i] = pDXView->u.pShaderResourceView;
5108 }
5109 else
5110 papShaderResourceView[i] = NULL;
5111 }
5112
5113 dxShaderResourceViewSet(pDevice, type, 0, SVGA3D_DX_MAX_SRVIEWS, papShaderResourceView);
5114 return VINF_SUCCESS;
5115}
5116
5117
5118static DECLCALLBACK(int) vmsvga3dBackDXSetShaderResources(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t startView, SVGA3dShaderType type, uint32_t cShaderResourceViewId, SVGA3dShaderResourceViewId const *paShaderResourceViewId)
5119{
5120 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5121 RT_NOREF(pBackend);
5122
5123 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5124 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5125
5126 RT_NOREF(startView, type, cShaderResourceViewId, paShaderResourceViewId);
5127
5128 return VINF_SUCCESS;
5129}
5130
5131
5132static DECLCALLBACK(int) vmsvga3dBackDXSetShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, SVGA3dShaderType type)
5133{
5134 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5135 RT_NOREF(pBackend);
5136
5137 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5138 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5139
5140 RT_NOREF(shaderId, type);
5141
5142 return VINF_SUCCESS;
5143}
5144
5145
5146static DECLCALLBACK(int) vmsvga3dBackDXSetSamplers(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t startSampler, SVGA3dShaderType type, uint32_t cSamplerId, SVGA3dSamplerId const *paSamplerId)
5147{
5148 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5149 RT_NOREF(pBackend);
5150
5151 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5152 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5153
5154 ID3D11SamplerState *papSamplerState[SVGA3D_DX_MAX_SAMPLERS];
5155 for (uint32_t i = 0; i < cSamplerId; ++i)
5156 {
5157 SVGA3dSamplerId samplerId = paSamplerId[i];
5158 if (samplerId != SVGA3D_INVALID_ID)
5159 {
5160 ASSERT_GUEST_RETURN(samplerId < pDXContext->pBackendDXContext->cSamplerState, VERR_INVALID_PARAMETER);
5161 papSamplerState[i] = pDXContext->pBackendDXContext->papSamplerState[samplerId];
5162 }
5163 else
5164 papSamplerState[i] = NULL;
5165 }
5166
5167 dxSamplerSet(pDevice, type, startSampler, cSamplerId, papSamplerState);
5168 return VINF_SUCCESS;
5169}
5170
5171
5172static void dxSetupPipeline(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5173{
5174 /* Make sure that any draw operations on shader resource views have finished. */
5175 AssertCompile(RT_ELEMENTS(pDXContext->svgaDXContext.shaderState) == SVGA3D_NUM_SHADERTYPE);
5176 AssertCompile(RT_ELEMENTS(pDXContext->svgaDXContext.shaderState[0].shaderResources) == SVGA3D_DX_MAX_SRVIEWS);
5177
5178 int rc;
5179
5180 /* Unbind render target views because they mught be (re-)used as shader resource views. */
5181 DXDEVICE *pDXDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5182 pDXDevice->pImmediateContext->OMSetRenderTargets(0, NULL, NULL);
5183
5184 /*
5185 * Shader resources
5186 */
5187
5188 /* Make sure that the shader resource views exist. */
5189 for (uint32_t idxShaderState = 0; idxShaderState < SVGA3D_NUM_SHADERTYPE_DX10 /** @todo SVGA3D_NUM_SHADERTYPE*/; ++idxShaderState)
5190 {
5191 for (uint32_t idxSR = 0; idxSR < SVGA3D_DX_MAX_SRVIEWS; ++idxSR)
5192 {
5193 SVGA3dShaderResourceViewId const shaderResourceViewId = pDXContext->svgaDXContext.shaderState[idxShaderState].shaderResources[idxSR];
5194 if (shaderResourceViewId != SVGA3D_INVALID_ID)
5195 {
5196 ASSERT_GUEST_RETURN_VOID(shaderResourceViewId < pDXContext->pBackendDXContext->cShaderResourceView);
5197
5198 SVGACOTableDXSRViewEntry const *pSRViewEntry = dxGetShaderResourceViewEntry(pDXContext, shaderResourceViewId);
5199 AssertContinue(pSRViewEntry != NULL);
5200
5201 uint32_t const sid = pSRViewEntry->sid;
5202
5203 PVMSVGA3DSURFACE pSurface;
5204 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
5205 AssertRCReturnVoid(rc);
5206
5207 /* The guest might have invalidated the surface in which case pSurface->pBackendSurface is NULL. */
5208 /** @todo This is not needed for "single DX device" mode. */
5209 if (pSurface->pBackendSurface)
5210 {
5211 /* Wait for the surface to finish drawing. */
5212 dxSurfaceWait(pThisCC->svga.p3dState, pSurface, pDXContext->cid);
5213 }
5214
5215 /* If a view has not been created yet, do it now. */
5216 if (!pDXContext->pBackendDXContext->paShaderResourceView[shaderResourceViewId].u.pView)
5217 {
5218//DEBUG_BREAKPOINT_TEST();
5219 LogFunc(("Re-creating SRV: sid=%u srvid = %u\n", sid, shaderResourceViewId));
5220 rc = dxDefineShaderResourceView(pThisCC, pDXContext, shaderResourceViewId, pSRViewEntry);
5221 AssertContinue(RT_SUCCESS(rc));
5222 }
5223
5224 LogFunc(("srv[%d][%d] sid = %u, srvid = %u\n", idxShaderState, idxSR, sid, shaderResourceViewId));
5225
5226#ifdef DUMP_BITMAPS
5227 SVGA3dSurfaceImageId image;
5228 image.sid = sid;
5229 image.face = 0;
5230 image.mipmap = 0;
5231 VMSVGA3D_MAPPED_SURFACE map;
5232 int rc2 = vmsvga3dSurfaceMap(pThisCC, &image, NULL, VMSVGA3D_SURFACE_MAP_READ, &map);
5233 if (RT_SUCCESS(rc2))
5234 {
5235 vmsvga3dMapWriteBmpFile(&map, "sr-");
5236 vmsvga3dSurfaceUnmap(pThisCC, &image, &map, /* fWritten = */ false);
5237 }
5238 else
5239 Log(("Map failed %Rrc\n", rc));
5240#endif
5241 }
5242 }
5243
5244 /* Set shader resources. */
5245 rc = dxSetShaderResources(pThisCC, pDXContext, (SVGA3dShaderType)(idxShaderState + SVGA3D_SHADERTYPE_MIN));
5246 AssertRC(rc);
5247 }
5248
5249 /*
5250 * Render targets
5251 */
5252
5253 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5254 AssertReturnVoid(pDevice->pDevice);
5255
5256 /* Make sure that the render target views exist. Similar to SRVs. */
5257 if (pDXContext->svgaDXContext.renderState.depthStencilViewId != SVGA3D_INVALID_ID)
5258 {
5259 uint32_t const viewId = pDXContext->svgaDXContext.renderState.depthStencilViewId;
5260
5261 ASSERT_GUEST_RETURN_VOID(viewId < pDXContext->pBackendDXContext->cDepthStencilView);
5262
5263 SVGACOTableDXDSViewEntry const *pDSViewEntry = dxGetDepthStencilViewEntry(pDXContext, viewId);
5264 AssertReturnVoid(pDSViewEntry != NULL);
5265
5266 PVMSVGA3DSURFACE pSurface;
5267 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pDSViewEntry->sid, &pSurface);
5268 AssertRCReturnVoid(rc);
5269
5270 /* If a view has not been created yet, do it now. */
5271 if (!pDXContext->pBackendDXContext->paDepthStencilView[viewId].u.pView)
5272 {
5273//DEBUG_BREAKPOINT_TEST();
5274 LogFunc(("Re-creating DSV: sid=%u dsvid = %u\n", pDSViewEntry->sid, viewId));
5275 rc = dxDefineDepthStencilView(pThisCC, pDXContext, viewId, pDSViewEntry);
5276 AssertReturnVoid(RT_SUCCESS(rc));
5277 }
5278 }
5279
5280 for (uint32_t i = 0; i < SVGA3D_MAX_SIMULTANEOUS_RENDER_TARGETS; ++i)
5281 {
5282 if (pDXContext->svgaDXContext.renderState.renderTargetViewIds[i] != SVGA3D_INVALID_ID)
5283 {
5284 uint32_t const viewId = pDXContext->svgaDXContext.renderState.renderTargetViewIds[i];
5285
5286 ASSERT_GUEST_RETURN_VOID(viewId < pDXContext->pBackendDXContext->cRenderTargetView);
5287
5288 SVGACOTableDXRTViewEntry const *pRTViewEntry = dxGetRenderTargetViewEntry(pDXContext, viewId);
5289 AssertReturnVoid(pRTViewEntry != NULL);
5290
5291 PVMSVGA3DSURFACE pSurface;
5292 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pRTViewEntry->sid, &pSurface);
5293 AssertRCReturnVoid(rc);
5294
5295 /* If a view has not been created yet, do it now. */
5296 if (!pDXContext->pBackendDXContext->paRenderTargetView[viewId].u.pView)
5297 {
5298//DEBUG_BREAKPOINT_TEST();
5299 LogFunc(("Re-creating RTV: sid=%u rtvid = %u\n", pRTViewEntry->sid, viewId));
5300 rc = dxDefineRenderTargetView(pThisCC, pDXContext, viewId, pRTViewEntry);
5301 AssertReturnVoid(RT_SUCCESS(rc));
5302 }
5303 }
5304 }
5305
5306 /* Set render targets. */
5307 rc = dxSetRenderTargets(pThisCC, pDXContext);
5308 AssertRC(rc);
5309
5310 /*
5311 * Shaders
5312 */
5313
5314 for (uint32_t idxShaderState = 0; idxShaderState < SVGA3D_NUM_SHADERTYPE_DX10 /** @todo SVGA3D_NUM_SHADERTYPE*/; ++idxShaderState)
5315 {
5316 DXSHADER *pDXShader;
5317 SVGA3dShaderType const shaderType = (SVGA3dShaderType)(idxShaderState + SVGA3D_SHADERTYPE_MIN);
5318 SVGA3dShaderId const shaderId = pDXContext->svgaDXContext.shaderState[idxShaderState].shaderId;
5319
5320 if (shaderId != SVGA3D_INVALID_ID)
5321 {
5322 pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
5323 if (pDXShader->pShader == NULL)
5324 {
5325 /* Create a new shader. */
5326 Log(("Shader: cid=%u shid=%u type=%d\n", pDXContext->cid, shaderId, pDXShader->enmShaderType));
5327
5328 /* Apply resource types to a pixel shader. */
5329 if (shaderType == SVGA3D_SHADERTYPE_PS)
5330 {
5331 VGPU10_RESOURCE_DIMENSION aResourceType[SVGA3D_DX_MAX_SRVIEWS];
5332 RT_ZERO(aResourceType);
5333 uint32_t cResourceType = 0;
5334
5335 for (uint32_t idxSR = 0; idxSR < SVGA3D_DX_MAX_SRVIEWS; ++idxSR)
5336 {
5337 SVGA3dShaderResourceViewId const shaderResourceViewId = pDXContext->svgaDXContext.shaderState[idxShaderState].shaderResources[idxSR];
5338 if (shaderResourceViewId != SVGA3D_INVALID_ID)
5339 {
5340 SVGACOTableDXSRViewEntry const *pSRViewEntry = dxGetShaderResourceViewEntry(pDXContext, shaderResourceViewId);
5341 AssertContinue(pSRViewEntry != NULL);
5342
5343 PVMSVGA3DSURFACE pSurface;
5344 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pSRViewEntry->sid, &pSurface);
5345 AssertRCReturnVoid(rc);
5346
5347 switch (pSRViewEntry->resourceDimension)
5348 {
5349 case SVGA3D_RESOURCE_BUFFEREX:
5350 case SVGA3D_RESOURCE_BUFFER:
5351 aResourceType[idxSR] = VGPU10_RESOURCE_DIMENSION_BUFFER;
5352 break;
5353 case SVGA3D_RESOURCE_TEXTURE1D:
5354 if (pSurface->surfaceDesc.numArrayElements <= 1)
5355 aResourceType[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURE1D;
5356 else
5357 aResourceType[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURE1DARRAY;
5358 break;
5359 case SVGA3D_RESOURCE_TEXTURE2D:
5360 if (pSurface->surfaceDesc.numArrayElements <= 1)
5361 aResourceType[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
5362 else
5363 aResourceType[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURE2DARRAY;
5364 break;
5365 case SVGA3D_RESOURCE_TEXTURE3D:
5366 aResourceType[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURE3D;
5367 break;
5368 case SVGA3D_RESOURCE_TEXTURECUBE:
5369 if (pSurface->surfaceDesc.numArrayElements <= 6)
5370 aResourceType[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURECUBE;
5371 else
5372 aResourceType[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURECUBEARRAY;
5373 break;
5374 default:
5375 ASSERT_GUEST_FAILED();
5376 aResourceType[idxSR] = VGPU10_RESOURCE_DIMENSION_TEXTURE2D;
5377 }
5378
5379 cResourceType = idxSR + 1;
5380 }
5381 }
5382
5383 rc = DXShaderUpdateResourceTypes(&pDXShader->shaderInfo, aResourceType, cResourceType);
5384 AssertRC(rc); /* Ignore rc because the shader will most likely work anyway. */
5385 }
5386
5387 rc = DXShaderCreateDXBC(&pDXShader->shaderInfo, &pDXShader->pvDXBC, &pDXShader->cbDXBC);
5388 if (RT_SUCCESS(rc))
5389 {
5390#ifdef LOG_ENABLED
5391 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5392 if (pBackend->pfnD3DDisassemble && LogIs6Enabled())
5393 {
5394 ID3D10Blob *pBlob = 0;
5395 HRESULT hr2 = pBackend->pfnD3DDisassemble(pDXShader->pvDXBC, pDXShader->cbDXBC, 0, NULL, &pBlob);
5396 if (SUCCEEDED(hr2) && pBlob && pBlob->GetBufferSize())
5397 Log6(("%s\n", pBlob->GetBufferPointer()));
5398 else
5399 AssertFailed();
5400 D3D_RELEASE(pBlob);
5401 }
5402#endif
5403
5404 HRESULT hr = dxShaderCreate(pThisCC, pDXContext, pDXShader);
5405 if (FAILED(hr))
5406 rc = VERR_INVALID_STATE;
5407 }
5408 else
5409 rc = VERR_NO_MEMORY;
5410 }
5411 }
5412 else
5413 pDXShader = NULL;
5414
5415 if (RT_SUCCESS(rc))
5416 dxShaderSet(pThisCC, pDXContext, shaderType, pDXShader);
5417
5418 AssertRC(rc);
5419 }
5420
5421 /*
5422 * InputLayout
5423 */
5424 SVGA3dElementLayoutId const elementLayoutId = pDXContext->svgaDXContext.inputAssembly.layoutId;
5425 ID3D11InputLayout *pInputLayout = NULL;
5426 if (elementLayoutId != SVGA3D_INVALID_ID)
5427 {
5428 DXELEMENTLAYOUT *pDXElementLayout = &pDXContext->pBackendDXContext->paElementLayout[elementLayoutId];
5429 if (!pDXElementLayout->pElementLayout)
5430 {
5431 uint32_t const idxShaderState = SVGA3D_SHADERTYPE_VS - SVGA3D_SHADERTYPE_MIN;
5432 uint32_t const shid = pDXContext->svgaDXContext.shaderState[idxShaderState].shaderId;
5433 if (shid < pDXContext->pBackendDXContext->cShader)
5434 {
5435 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shid];
5436 if (pDXShader->pvDXBC)
5437 {
5438 HRESULT hr = pDevice->pDevice->CreateInputLayout(pDXElementLayout->aElementDesc,
5439 pDXElementLayout->cElementDesc,
5440 pDXShader->pvDXBC,
5441 pDXShader->cbDXBC,
5442 &pDXElementLayout->pElementLayout);
5443 Assert(SUCCEEDED(hr)); RT_NOREF(hr);
5444 }
5445 else
5446 LogRelMax(16, ("VMSVGA: DX shader bytecode is not available in DXSetInputLayout: shid = %u\n", shid));
5447 }
5448 else
5449 LogRelMax(16, ("VMSVGA: DX shader is not set in DXSetInputLayout: shid = 0x%x\n", shid));
5450 }
5451
5452 pInputLayout = pDXElementLayout->pElementLayout;
5453 }
5454
5455 pDevice->pImmediateContext->IASetInputLayout(pInputLayout);
5456}
5457
5458
5459static DECLCALLBACK(int) vmsvga3dBackDXDraw(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t vertexCount, uint32_t startVertexLocation)
5460{
5461 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5462 RT_NOREF(pBackend);
5463
5464 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5465 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5466
5467 dxSetupPipeline(pThisCC, pDXContext);
5468
5469 if (pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN)
5470 pDevice->pImmediateContext->Draw(vertexCount, startVertexLocation);
5471 else
5472 {
5473 /*
5474 * Emulate SVGA3D_PRIMITIVE_TRIANGLEFAN using an indexed draw of a triangle list.
5475 */
5476
5477 /* Make sure that 16 bit indices are enough. */
5478 if (vertexCount > 65535)
5479 {
5480 LogRelMax(1, ("VMSVGA: ignore Draw(TRIANGLEFAN, %u)\n", vertexCount));
5481 return VERR_NOT_SUPPORTED;
5482 }
5483
5484 /* Generate indices. */
5485 UINT const IndexCount = 3 * (vertexCount - 2); /* 3_per_triangle * num_triangles */
5486 UINT const cbAlloc = IndexCount * sizeof(USHORT);
5487 USHORT *paIndices = (USHORT *)RTMemAlloc(cbAlloc);
5488 AssertReturn(paIndices, VERR_NO_MEMORY);
5489 USHORT iVertex = 1;
5490 for (UINT i = 0; i < IndexCount; i+= 3)
5491 {
5492 paIndices[i] = 0;
5493 paIndices[i + 1] = iVertex;
5494 ++iVertex;
5495 paIndices[i + 2] = iVertex;
5496 }
5497
5498 D3D11_SUBRESOURCE_DATA InitData;
5499 InitData.pSysMem = paIndices;
5500 InitData.SysMemPitch = cbAlloc;
5501 InitData.SysMemSlicePitch = cbAlloc;
5502
5503 D3D11_BUFFER_DESC bd;
5504 RT_ZERO(bd);
5505 bd.ByteWidth = cbAlloc;
5506 bd.Usage = D3D11_USAGE_IMMUTABLE;
5507 bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
5508 //bd.CPUAccessFlags = 0;
5509 //bd.MiscFlags = 0;
5510 //bd.StructureByteStride = 0;
5511
5512 ID3D11Buffer *pIndexBuffer = 0;
5513 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, &InitData, &pIndexBuffer);
5514 Assert(SUCCEEDED(hr));RT_NOREF(hr);
5515
5516 /* Save the current index buffer. */
5517 ID3D11Buffer *pSavedIndexBuffer = 0;
5518 DXGI_FORMAT SavedFormat = DXGI_FORMAT_UNKNOWN;
5519 UINT SavedOffset = 0;
5520 pDevice->pImmediateContext->IAGetIndexBuffer(&pSavedIndexBuffer, &SavedFormat, &SavedOffset);
5521
5522 /* Set up the device state. */
5523 pDevice->pImmediateContext->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
5524 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5525
5526 UINT const StartIndexLocation = 0;
5527 INT const BaseVertexLocation = startVertexLocation;
5528 pDevice->pImmediateContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation);
5529
5530 /* Restore the device state. */
5531 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
5532 pDevice->pImmediateContext->IASetIndexBuffer(pSavedIndexBuffer, SavedFormat, SavedOffset);
5533 D3D_RELEASE(pSavedIndexBuffer);
5534
5535 /* Cleanup. */
5536 D3D_RELEASE(pIndexBuffer);
5537 RTMemFree(paIndices);
5538 }
5539
5540 /* Note which surfaces are being drawn. */
5541 dxTrackRenderTargets(pThisCC, pDXContext);
5542
5543 return VINF_SUCCESS;
5544}
5545
5546static int dxReadBuffer(DXDEVICE *pDevice, ID3D11Buffer *pBuffer, UINT Offset, UINT Bytes, void **ppvData, uint32_t *pcbData)
5547{
5548 D3D11_BUFFER_DESC desc;
5549 RT_ZERO(desc);
5550 pBuffer->GetDesc(&desc);
5551
5552 AssertReturn( Offset < desc.ByteWidth
5553 && Bytes <= desc.ByteWidth - Offset, VERR_INVALID_STATE);
5554
5555 void *pvData = RTMemAlloc(Bytes);
5556 if (!pvData)
5557 return VERR_NO_MEMORY;
5558
5559 *ppvData = pvData;
5560 *pcbData = Bytes;
5561
5562 int rc = dxStagingBufferRealloc(pDevice, Bytes);
5563 if (RT_SUCCESS(rc))
5564 {
5565 /* Copy from the buffer to the staging buffer. */
5566 ID3D11Resource *pDstResource = pDevice->pStagingBuffer;
5567 UINT DstSubresource = 0;
5568 UINT DstX = Offset;
5569 UINT DstY = 0;
5570 UINT DstZ = 0;
5571 ID3D11Resource *pSrcResource = pBuffer;
5572 UINT SrcSubresource = 0;
5573 D3D11_BOX SrcBox;
5574 SrcBox.left = 0;
5575 SrcBox.top = 0;
5576 SrcBox.front = 0;
5577 SrcBox.right = Bytes;
5578 SrcBox.bottom = 1;
5579 SrcBox.back = 1;
5580 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
5581 pSrcResource, SrcSubresource, &SrcBox);
5582
5583 D3D11_MAPPED_SUBRESOURCE mappedResource;
5584 UINT const Subresource = 0; /* Buffers have only one subresource. */
5585 HRESULT hr = pDevice->pImmediateContext->Map(pDevice->pStagingBuffer, Subresource,
5586 D3D11_MAP_READ, /* MapFlags = */ 0, &mappedResource);
5587 if (SUCCEEDED(hr))
5588 {
5589 memcpy(pvData, mappedResource.pData, Bytes);
5590
5591 /* Unmap the staging buffer. */
5592 pDevice->pImmediateContext->Unmap(pDevice->pStagingBuffer, Subresource);
5593 }
5594 else
5595 AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
5596
5597 }
5598
5599 if (RT_FAILURE(rc))
5600 {
5601 RTMemFree(*ppvData);
5602 *ppvData = NULL;
5603 *pcbData = 0;
5604 }
5605
5606 return rc;
5607}
5608
5609
5610static int dxDrawIndexedTriangleFan(DXDEVICE *pDevice, uint32_t IndexCountTF, uint32_t StartIndexLocationTF, int32_t BaseVertexLocationTF)
5611{
5612 /*
5613 * Emulate an indexed SVGA3D_PRIMITIVE_TRIANGLEFAN using an indexed draw of triangle list.
5614 */
5615
5616 /* Make sure that 16 bit indices are enough. */
5617 if (IndexCountTF > 65535)
5618 {
5619 LogRelMax(1, ("VMSVGA: ignore DrawIndexed(TRIANGLEFAN, %u)\n", IndexCountTF));
5620 return VERR_NOT_SUPPORTED;
5621 }
5622
5623 /* Save the current index buffer. */
5624 ID3D11Buffer *pSavedIndexBuffer = 0;
5625 DXGI_FORMAT SavedFormat = DXGI_FORMAT_UNKNOWN;
5626 UINT SavedOffset = 0;
5627 pDevice->pImmediateContext->IAGetIndexBuffer(&pSavedIndexBuffer, &SavedFormat, &SavedOffset);
5628
5629 AssertReturn( SavedFormat == DXGI_FORMAT_R16_UINT
5630 || SavedFormat == DXGI_FORMAT_R32_UINT, VERR_NOT_SUPPORTED);
5631
5632 /* How many bytes are used by triangle fan indices. */
5633 UINT const BytesPerIndexTF = SavedFormat == DXGI_FORMAT_R16_UINT ? 2 : 4;
5634 UINT const BytesTF = BytesPerIndexTF * IndexCountTF;
5635
5636 /* Read the current index buffer content to obtain indices. */
5637 void *pvDataTF;
5638 uint32_t cbDataTF;
5639 int rc = dxReadBuffer(pDevice, pSavedIndexBuffer, StartIndexLocationTF, BytesTF, &pvDataTF, &cbDataTF);
5640 AssertRCReturn(rc, rc);
5641 AssertReturnStmt(cbDataTF >= BytesPerIndexTF, RTMemFree(pvDataTF), VERR_INVALID_STATE);
5642
5643 /* Generate indices for triangle list. */
5644 UINT const IndexCount = 3 * (IndexCountTF - 2); /* 3_per_triangle * num_triangles */
5645 UINT const cbAlloc = IndexCount * sizeof(USHORT);
5646 USHORT *paIndices = (USHORT *)RTMemAlloc(cbAlloc);
5647 AssertReturnStmt(paIndices, RTMemFree(pvDataTF), VERR_NO_MEMORY);
5648
5649 USHORT iVertex = 1;
5650 if (BytesPerIndexTF == 2)
5651 {
5652 USHORT *paIndicesTF = (USHORT *)pvDataTF;
5653 for (UINT i = 0; i < IndexCount; i+= 3)
5654 {
5655 paIndices[i] = paIndicesTF[0];
5656 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5657 paIndices[i + 1] = paIndicesTF[iVertex];
5658 ++iVertex;
5659 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5660 paIndices[i + 2] = paIndicesTF[iVertex];
5661 }
5662 }
5663 else
5664 {
5665 UINT *paIndicesTF = (UINT *)pvDataTF;
5666 for (UINT i = 0; i < IndexCount; i+= 3)
5667 {
5668 paIndices[i] = paIndicesTF[0];
5669 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5670 paIndices[i + 1] = paIndicesTF[iVertex];
5671 ++iVertex;
5672 AssertBreakStmt(iVertex < IndexCountTF, rc = VERR_INVALID_STATE);
5673 paIndices[i + 2] = paIndicesTF[iVertex];
5674 }
5675 }
5676
5677 D3D11_SUBRESOURCE_DATA InitData;
5678 InitData.pSysMem = paIndices;
5679 InitData.SysMemPitch = cbAlloc;
5680 InitData.SysMemSlicePitch = cbAlloc;
5681
5682 D3D11_BUFFER_DESC bd;
5683 RT_ZERO(bd);
5684 bd.ByteWidth = cbAlloc;
5685 bd.Usage = D3D11_USAGE_IMMUTABLE;
5686 bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
5687 //bd.CPUAccessFlags = 0;
5688 //bd.MiscFlags = 0;
5689 //bd.StructureByteStride = 0;
5690
5691 ID3D11Buffer *pIndexBuffer = 0;
5692 HRESULT hr = pDevice->pDevice->CreateBuffer(&bd, &InitData, &pIndexBuffer);
5693 Assert(SUCCEEDED(hr));RT_NOREF(hr);
5694
5695 /* Set up the device state. */
5696 pDevice->pImmediateContext->IASetIndexBuffer(pIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
5697 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
5698
5699 UINT const StartIndexLocation = 0;
5700 INT const BaseVertexLocation = BaseVertexLocationTF;
5701 pDevice->pImmediateContext->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation);
5702
5703 /* Restore the device state. */
5704 pDevice->pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
5705 pDevice->pImmediateContext->IASetIndexBuffer(pSavedIndexBuffer, SavedFormat, SavedOffset);
5706 D3D_RELEASE(pSavedIndexBuffer);
5707
5708 /* Cleanup. */
5709 D3D_RELEASE(pIndexBuffer);
5710 RTMemFree(paIndices);
5711 RTMemFree(pvDataTF);
5712
5713 return VINF_SUCCESS;
5714}
5715
5716
5717static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexed(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t indexCount, uint32_t startIndexLocation, int32_t baseVertexLocation)
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 if (pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN)
5728 pDevice->pImmediateContext->DrawIndexed(indexCount, startIndexLocation, baseVertexLocation);
5729 else
5730 {
5731 dxDrawIndexedTriangleFan(pDevice, indexCount, startIndexLocation, baseVertexLocation);
5732 }
5733
5734 /* Note which surfaces are being drawn. */
5735 dxTrackRenderTargets(pThisCC, pDXContext);
5736
5737 return VINF_SUCCESS;
5738}
5739
5740
5741static DECLCALLBACK(int) vmsvga3dBackDXDrawInstanced(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
5742 uint32_t vertexCountPerInstance, uint32_t instanceCount, uint32_t startVertexLocation, uint32_t startInstanceLocation)
5743{
5744 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5745 RT_NOREF(pBackend);
5746
5747 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5748 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5749
5750 dxSetupPipeline(pThisCC, pDXContext);
5751
5752 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
5753
5754 pDevice->pImmediateContext->DrawInstanced(vertexCountPerInstance, instanceCount, startVertexLocation, startInstanceLocation);
5755
5756 /* Note which surfaces are being drawn. */
5757 dxTrackRenderTargets(pThisCC, pDXContext);
5758
5759 return VINF_SUCCESS;
5760}
5761
5762
5763static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexedInstanced(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
5764 uint32_t indexCountPerInstance, uint32_t instanceCount, uint32_t startIndexLocation, int32_t baseVertexLocation, uint32_t startInstanceLocation)
5765{
5766 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5767 RT_NOREF(pBackend);
5768
5769 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5770 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5771
5772 dxSetupPipeline(pThisCC, pDXContext);
5773
5774 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
5775
5776 pDevice->pImmediateContext->DrawIndexedInstanced(indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation);
5777
5778 /* Note which surfaces are being drawn. */
5779 dxTrackRenderTargets(pThisCC, pDXContext);
5780
5781 return VINF_SUCCESS;
5782}
5783
5784
5785static DECLCALLBACK(int) vmsvga3dBackDXDrawAuto(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5786{
5787 Assert(pDXContext->svgaDXContext.inputAssembly.topology != SVGA3D_PRIMITIVE_TRIANGLEFAN);
5788 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5789
5790 dxSetupPipeline(pThisCC, pDXContext);
5791
5792 RT_NOREF(pBackend, pDXContext);
5793 AssertFailed(); /** @todo Implement */
5794 return VERR_NOT_IMPLEMENTED;
5795}
5796
5797
5798static DECLCALLBACK(int) vmsvga3dBackDXSetInputLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId)
5799{
5800 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5801 RT_NOREF(pBackend);
5802
5803 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5804 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5805
5806 RT_NOREF(elementLayoutId);
5807
5808 return VINF_SUCCESS;
5809}
5810
5811
5812static DECLCALLBACK(int) vmsvga3dBackDXSetVertexBuffers(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t startBuffer, uint32_t cVertexBuffer, SVGA3dVertexBuffer const *paVertexBuffer)
5813{
5814 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5815 RT_NOREF(pBackend);
5816
5817 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5818 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5819
5820 /* For each paVertexBuffer[i]:
5821 * If the vertex buffer object does not exist then create it.
5822 * If the surface has been updated by the guest then update the buffer object.
5823 * Use IASetVertexBuffers to set the buffers.
5824 */
5825
5826 ID3D11Buffer *paResources[SVGA3D_DX_MAX_VERTEXBUFFERS];
5827 UINT paStride[SVGA3D_DX_MAX_VERTEXBUFFERS];
5828 UINT paOffset[SVGA3D_DX_MAX_VERTEXBUFFERS];
5829
5830 for (uint32_t i = 0; i < cVertexBuffer; ++i)
5831 {
5832 uint32_t const idxVertexBuffer = startBuffer + i;
5833
5834 /* Get corresponding resource. Create the buffer if does not yet exist. */
5835 if (paVertexBuffer[i].sid != SVGA_ID_INVALID)
5836 {
5837 PVMSVGA3DSURFACE pSurface;
5838 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, paVertexBuffer[i].sid, &pSurface);
5839 AssertRCReturn(rc, rc);
5840
5841 if (pSurface->pBackendSurface == NULL)
5842 {
5843 /* Create the resource and initialize it with the current surface data. */
5844 rc = vmsvga3dBackSurfaceCreateBuffer(pThisCC, pDXContext, pSurface);
5845 AssertRCReturn(rc, rc);
5846 }
5847
5848 Assert(pSurface->pBackendSurface->u.pBuffer);
5849 paResources[idxVertexBuffer] = pSurface->pBackendSurface->u.pBuffer;
5850 paStride[idxVertexBuffer] = paVertexBuffer[i].stride;
5851 paOffset[idxVertexBuffer] = paVertexBuffer[i].offset;
5852 }
5853 else
5854 {
5855 paResources[idxVertexBuffer] = NULL;
5856 paStride[idxVertexBuffer] = 0;
5857 paOffset[idxVertexBuffer] = 0;
5858 }
5859 }
5860
5861 pDevice->pImmediateContext->IASetVertexBuffers(startBuffer, cVertexBuffer,
5862 &paResources[startBuffer], &paStride[startBuffer], &paOffset[startBuffer]);
5863
5864 return VINF_SUCCESS;
5865}
5866
5867
5868static DECLCALLBACK(int) vmsvga3dBackDXSetIndexBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSurfaceId sid, SVGA3dSurfaceFormat format, uint32_t offset)
5869{
5870 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5871 RT_NOREF(pBackend);
5872
5873 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5874 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5875
5876 /* Get corresponding resource. Create the buffer if does not yet exist. */
5877 ID3D11Buffer *pResource;
5878 DXGI_FORMAT enmDxgiFormat;
5879
5880 if (sid != SVGA_ID_INVALID)
5881 {
5882 PVMSVGA3DSURFACE pSurface;
5883 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
5884 AssertRCReturn(rc, rc);
5885
5886 if (pSurface->pBackendSurface == NULL)
5887 {
5888 /* Create the resource and initialize it with the current surface data. */
5889 rc = vmsvga3dBackSurfaceCreateBuffer(pThisCC, pDXContext, pSurface);
5890 AssertRCReturn(rc, rc);
5891 }
5892
5893 pResource = pSurface->pBackendSurface->u.pBuffer;
5894 enmDxgiFormat = vmsvgaDXSurfaceFormat2Dxgi(format);
5895 AssertReturn(enmDxgiFormat == DXGI_FORMAT_R16_UINT || enmDxgiFormat == DXGI_FORMAT_R32_UINT, VERR_INVALID_PARAMETER);
5896 }
5897 else
5898 {
5899 pResource = NULL;
5900 enmDxgiFormat = DXGI_FORMAT_UNKNOWN;
5901 }
5902
5903 pDevice->pImmediateContext->IASetIndexBuffer(pResource, enmDxgiFormat, offset);
5904 return VINF_SUCCESS;
5905}
5906
5907static D3D11_PRIMITIVE_TOPOLOGY dxTopology(SVGA3dPrimitiveType primitiveType)
5908{
5909 static D3D11_PRIMITIVE_TOPOLOGY const aD3D11PrimitiveTopology[SVGA3D_PRIMITIVE_MAX] =
5910 {
5911 D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED,
5912 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
5913 D3D11_PRIMITIVE_TOPOLOGY_POINTLIST,
5914 D3D11_PRIMITIVE_TOPOLOGY_LINELIST,
5915 D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP,
5916 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP,
5917 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, /* SVGA3D_PRIMITIVE_TRIANGLEFAN: No FAN in D3D11. */
5918 D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ,
5919 D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ,
5920 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ,
5921 D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ,
5922 D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST,
5923 D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST,
5924 D3D11_PRIMITIVE_TOPOLOGY_3_CONTROL_POINT_PATCHLIST,
5925 D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST,
5926 D3D11_PRIMITIVE_TOPOLOGY_5_CONTROL_POINT_PATCHLIST,
5927 D3D11_PRIMITIVE_TOPOLOGY_6_CONTROL_POINT_PATCHLIST,
5928 D3D11_PRIMITIVE_TOPOLOGY_7_CONTROL_POINT_PATCHLIST,
5929 D3D11_PRIMITIVE_TOPOLOGY_8_CONTROL_POINT_PATCHLIST,
5930 D3D11_PRIMITIVE_TOPOLOGY_9_CONTROL_POINT_PATCHLIST,
5931 D3D11_PRIMITIVE_TOPOLOGY_10_CONTROL_POINT_PATCHLIST,
5932 D3D11_PRIMITIVE_TOPOLOGY_11_CONTROL_POINT_PATCHLIST,
5933 D3D11_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST,
5934 D3D11_PRIMITIVE_TOPOLOGY_13_CONTROL_POINT_PATCHLIST,
5935 D3D11_PRIMITIVE_TOPOLOGY_14_CONTROL_POINT_PATCHLIST,
5936 D3D11_PRIMITIVE_TOPOLOGY_15_CONTROL_POINT_PATCHLIST,
5937 D3D11_PRIMITIVE_TOPOLOGY_16_CONTROL_POINT_PATCHLIST,
5938 D3D11_PRIMITIVE_TOPOLOGY_17_CONTROL_POINT_PATCHLIST,
5939 D3D11_PRIMITIVE_TOPOLOGY_18_CONTROL_POINT_PATCHLIST,
5940 D3D11_PRIMITIVE_TOPOLOGY_19_CONTROL_POINT_PATCHLIST,
5941 D3D11_PRIMITIVE_TOPOLOGY_20_CONTROL_POINT_PATCHLIST,
5942 D3D11_PRIMITIVE_TOPOLOGY_21_CONTROL_POINT_PATCHLIST,
5943 D3D11_PRIMITIVE_TOPOLOGY_22_CONTROL_POINT_PATCHLIST,
5944 D3D11_PRIMITIVE_TOPOLOGY_23_CONTROL_POINT_PATCHLIST,
5945 D3D11_PRIMITIVE_TOPOLOGY_24_CONTROL_POINT_PATCHLIST,
5946 D3D11_PRIMITIVE_TOPOLOGY_25_CONTROL_POINT_PATCHLIST,
5947 D3D11_PRIMITIVE_TOPOLOGY_26_CONTROL_POINT_PATCHLIST,
5948 D3D11_PRIMITIVE_TOPOLOGY_27_CONTROL_POINT_PATCHLIST,
5949 D3D11_PRIMITIVE_TOPOLOGY_28_CONTROL_POINT_PATCHLIST,
5950 D3D11_PRIMITIVE_TOPOLOGY_29_CONTROL_POINT_PATCHLIST,
5951 D3D11_PRIMITIVE_TOPOLOGY_30_CONTROL_POINT_PATCHLIST,
5952 D3D11_PRIMITIVE_TOPOLOGY_31_CONTROL_POINT_PATCHLIST,
5953 D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST,
5954 };
5955 return aD3D11PrimitiveTopology[primitiveType];
5956}
5957
5958static DECLCALLBACK(int) vmsvga3dBackDXSetTopology(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dPrimitiveType topology)
5959{
5960 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
5961 RT_NOREF(pBackend);
5962
5963 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5964 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5965
5966 D3D11_PRIMITIVE_TOPOLOGY const enmTopology = dxTopology(topology);
5967 pDevice->pImmediateContext->IASetPrimitiveTopology(enmTopology);
5968 return VINF_SUCCESS;
5969}
5970
5971
5972static int dxSetRenderTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
5973{
5974 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
5975 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
5976
5977 ID3D11RenderTargetView *apRenderTargetViews[SVGA3D_MAX_RENDER_TARGETS];
5978 RT_ZERO(apRenderTargetViews);
5979 for (uint32_t i = 0; i < SVGA3D_MAX_RENDER_TARGETS; ++i)
5980 {
5981 SVGA3dRenderTargetViewId const renderTargetViewId = pDXContext->svgaDXContext.renderState.renderTargetViewIds[i];
5982 if (renderTargetViewId != SVGA3D_INVALID_ID)
5983 {
5984 ASSERT_GUEST_RETURN(renderTargetViewId < pDXContext->pBackendDXContext->cRenderTargetView, VERR_INVALID_PARAMETER);
5985 apRenderTargetViews[i] = pDXContext->pBackendDXContext->paRenderTargetView[renderTargetViewId].u.pRenderTargetView;
5986 }
5987 }
5988
5989 ID3D11DepthStencilView *pDepthStencilView = NULL;
5990 SVGA3dDepthStencilViewId const depthStencilViewId = pDXContext->svgaDXContext.renderState.depthStencilViewId;
5991 if (depthStencilViewId != SVGA_ID_INVALID)
5992 pDepthStencilView = pDXContext->pBackendDXContext->paDepthStencilView[depthStencilViewId].u.pDepthStencilView;
5993
5994 pDevice->pImmediateContext->OMSetRenderTargets(SVGA3D_MAX_RENDER_TARGETS,
5995 apRenderTargetViews,
5996 pDepthStencilView);
5997 return VINF_SUCCESS;
5998}
5999
6000
6001static DECLCALLBACK(int) vmsvga3dBackDXSetRenderTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, uint32_t cRenderTargetViewId, SVGA3dRenderTargetViewId const *paRenderTargetViewId)
6002{
6003 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6004 RT_NOREF(pBackend);
6005
6006 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6007 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6008
6009 RT_NOREF(depthStencilViewId, cRenderTargetViewId, paRenderTargetViewId);
6010
6011 return VINF_SUCCESS;
6012}
6013
6014
6015static DECLCALLBACK(int) vmsvga3dBackDXSetBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dBlendStateId blendId, float const blendFactor[4], uint32_t sampleMask)
6016{
6017 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6018 RT_NOREF(pBackend);
6019
6020 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6021 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6022
6023 if (blendId != SVGA3D_INVALID_ID)
6024 {
6025 ID3D11BlendState *pBlendState = pDXContext->pBackendDXContext->papBlendState[blendId];
6026 pDevice->pImmediateContext->OMSetBlendState(pBlendState, blendFactor, sampleMask);
6027 }
6028 else
6029 pDevice->pImmediateContext->OMSetBlendState(NULL, NULL, 0);
6030
6031 return VINF_SUCCESS;
6032}
6033
6034
6035static DECLCALLBACK(int) vmsvga3dBackDXSetDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId, uint32_t stencilRef)
6036{
6037 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6038 RT_NOREF(pBackend);
6039
6040 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6041 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6042
6043 if (depthStencilId != SVGA3D_INVALID_ID)
6044 {
6045 ID3D11DepthStencilState *pDepthStencilState = pDXContext->pBackendDXContext->papDepthStencilState[depthStencilId];
6046 pDevice->pImmediateContext->OMSetDepthStencilState(pDepthStencilState, stencilRef);
6047 }
6048 else
6049 pDevice->pImmediateContext->OMSetDepthStencilState(NULL, 0);
6050
6051 return VINF_SUCCESS;
6052}
6053
6054
6055static DECLCALLBACK(int) vmsvga3dBackDXSetRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId)
6056{
6057 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6058 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6059 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6060
6061 RT_NOREF(pBackend);
6062
6063 if (rasterizerId != SVGA3D_INVALID_ID)
6064 {
6065 ID3D11RasterizerState *pRasterizerState = pDXContext->pBackendDXContext->papRasterizerState[rasterizerId];
6066 pDevice->pImmediateContext->RSSetState(pRasterizerState);
6067 }
6068 else
6069 pDevice->pImmediateContext->RSSetState(NULL);
6070
6071 return VINF_SUCCESS;
6072}
6073
6074static D3D11_QUERY dxQueryType(SVGA3dQueryType type)
6075{
6076 switch (type)
6077 {
6078 case SVGA3D_QUERYTYPE_OCCLUSION: return D3D11_QUERY_OCCLUSION;
6079 case SVGA3D_QUERYTYPE_TIMESTAMP: return D3D11_QUERY_TIMESTAMP;
6080 case SVGA3D_QUERYTYPE_TIMESTAMPDISJOINT: return D3D11_QUERY_TIMESTAMP_DISJOINT;
6081 case SVGA3D_QUERYTYPE_PIPELINESTATS: return D3D11_QUERY_PIPELINE_STATISTICS;
6082 case SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE: return D3D11_QUERY_OCCLUSION_PREDICATE;
6083 case SVGA3D_QUERYTYPE_STREAMOUTPUTSTATS: return D3D11_QUERY_SO_STATISTICS;
6084 case SVGA3D_QUERYTYPE_STREAMOVERFLOWPREDICATE: return D3D11_QUERY_SO_OVERFLOW_PREDICATE;
6085 case SVGA3D_QUERYTYPE_OCCLUSION64: return D3D11_QUERY_OCCLUSION;
6086 case SVGA3D_QUERYTYPE_SOSTATS_STREAM0: return D3D11_QUERY_SO_STATISTICS_STREAM0;
6087 case SVGA3D_QUERYTYPE_SOSTATS_STREAM1: return D3D11_QUERY_SO_STATISTICS_STREAM1;
6088 case SVGA3D_QUERYTYPE_SOSTATS_STREAM2: return D3D11_QUERY_SO_STATISTICS_STREAM2;
6089 case SVGA3D_QUERYTYPE_SOSTATS_STREAM3: return D3D11_QUERY_SO_STATISTICS_STREAM3;
6090 case SVGA3D_QUERYTYPE_SOP_STREAM0: return D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM0;
6091 case SVGA3D_QUERYTYPE_SOP_STREAM1: return D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM1;
6092 case SVGA3D_QUERYTYPE_SOP_STREAM2: return D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM2;
6093 case SVGA3D_QUERYTYPE_SOP_STREAM3: return D3D11_QUERY_SO_OVERFLOW_PREDICATE_STREAM3;
6094 default:
6095 break;
6096 }
6097 return D3D11_QUERY_EVENT;
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
6107 D3D11_QUERY_DESC desc;
6108 desc.Query = dxQueryType((SVGA3dQueryType)pEntry->type);
6109 desc.MiscFlags = 0;
6110 if (pEntry->flags & SVGA3D_DXQUERY_FLAG_PREDICATEHINT)
6111 desc.MiscFlags |= (UINT)D3D11_QUERY_MISC_PREDICATEHINT;
6112
6113 HRESULT hr = pDXDevice->pDevice->CreateQuery(&desc, &pDXQuery->pQuery);
6114 AssertReturn(SUCCEEDED(hr), VERR_INVALID_STATE);
6115
6116 return VINF_SUCCESS;
6117}
6118
6119
6120static int dxDestroyQuery(DXQUERY *pDXQuery)
6121{
6122 D3D_RELEASE(pDXQuery->pQuery);
6123 return VINF_SUCCESS;
6124}
6125
6126
6127static DECLCALLBACK(int) vmsvga3dBackDXDefineQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dQueryId queryId, SVGACOTableDXQueryEntry const *pEntry)
6128{
6129 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6130 RT_NOREF(pBackend);
6131
6132 return dxDefineQuery(pThisCC, pDXContext, queryId, pEntry);
6133}
6134
6135
6136static DECLCALLBACK(int) vmsvga3dBackDXDestroyQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dQueryId queryId)
6137{
6138 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6139 RT_NOREF(pBackend);
6140
6141 DXQUERY *pDXQuery = &pDXContext->pBackendDXContext->paQuery[queryId];
6142 dxDestroyQuery(pDXQuery);
6143
6144 return VINF_SUCCESS;
6145}
6146
6147
6148static DECLCALLBACK(int) vmsvga3dBackDXBindQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dQueryId queryId)
6149{
6150 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6151 RT_NOREF(pBackend, pDXContext, queryId);
6152
6153 return VINF_SUCCESS;
6154}
6155
6156
6157static int dxBeginQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dQueryId queryId, DXQUERY *pDXQuery)
6158{
6159 DXDEVICE *pDXDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6160 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
6161
6162 /* Begin is disabled for some queries. */
6163 SVGACOTableDXQueryEntry *pEntry = &pDXContext->cot.paQuery[queryId];
6164 if (pEntry->type == SVGA3D_QUERYTYPE_TIMESTAMP)
6165 return VINF_SUCCESS;
6166 pDXDevice->pImmediateContext->Begin(pDXQuery->pQuery);
6167 return VINF_SUCCESS;
6168}
6169
6170
6171static DECLCALLBACK(int) vmsvga3dBackDXBeginQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dQueryId queryId)
6172{
6173 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6174 RT_NOREF(pBackend);
6175
6176 DXQUERY *pDXQuery = &pDXContext->pBackendDXContext->paQuery[queryId];
6177 int rc = dxBeginQuery(pThisCC, pDXContext, queryId, pDXQuery);
6178 return rc;
6179}
6180
6181
6182static int dxEndQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, DXQUERY *pDXQuery)
6183{
6184 DXDEVICE *pDXDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6185 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
6186
6187 pDXDevice->pImmediateContext->End(pDXQuery->pQuery);
6188 return VINF_SUCCESS;
6189}
6190
6191
6192static DECLCALLBACK(int) vmsvga3dBackDXEndQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dQueryId queryId)
6193{
6194 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6195 RT_NOREF(pBackend);
6196
6197 DXQUERY *pDXQuery = &pDXContext->pBackendDXContext->paQuery[queryId];
6198 int rc = dxEndQuery(pThisCC, pDXContext, pDXQuery);
6199 return rc;
6200}
6201
6202
6203static int dxReadbackQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dQueryId queryId, DXQUERY *pDXQuery,
6204 void *pvData, uint32_t cbData, uint32_t *pcbOut)
6205{
6206 DXDEVICE *pDXDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6207 AssertReturn(pDXDevice->pDevice, VERR_INVALID_STATE);
6208
6209 SVGACOTableDXQueryEntry *pEntry = &pDXContext->cot.paQuery[queryId];
6210
6211 uint32_t cbRequired;
6212 switch (pEntry->type)
6213 {
6214 case SVGA3D_QUERYTYPE_OCCLUSION: cbRequired = sizeof(UINT64); break;
6215 case SVGA3D_QUERYTYPE_TIMESTAMP: cbRequired = sizeof(UINT64); break;
6216 case SVGA3D_QUERYTYPE_TIMESTAMPDISJOINT: cbRequired = sizeof(D3D11_QUERY_DATA_TIMESTAMP_DISJOINT); break;
6217 case SVGA3D_QUERYTYPE_PIPELINESTATS: cbRequired = sizeof(D3D11_QUERY_DATA_PIPELINE_STATISTICS); break;
6218 case SVGA3D_QUERYTYPE_OCCLUSIONPREDICATE: cbRequired = sizeof(BOOL); break;
6219 case SVGA3D_QUERYTYPE_STREAMOUTPUTSTATS: cbRequired = sizeof(D3D11_QUERY_DATA_SO_STATISTICS); break;
6220 case SVGA3D_QUERYTYPE_STREAMOVERFLOWPREDICATE: cbRequired = sizeof(BOOL); break;
6221 case SVGA3D_QUERYTYPE_OCCLUSION64: cbRequired = sizeof(UINT64); break;
6222 case SVGA3D_QUERYTYPE_SOSTATS_STREAM0: cbRequired = sizeof(D3D11_QUERY_DATA_SO_STATISTICS); break;
6223 case SVGA3D_QUERYTYPE_SOSTATS_STREAM1: cbRequired = sizeof(D3D11_QUERY_DATA_SO_STATISTICS); break;
6224 case SVGA3D_QUERYTYPE_SOSTATS_STREAM2: cbRequired = sizeof(D3D11_QUERY_DATA_SO_STATISTICS); break;
6225 case SVGA3D_QUERYTYPE_SOSTATS_STREAM3: cbRequired = sizeof(D3D11_QUERY_DATA_SO_STATISTICS); break;
6226 case SVGA3D_QUERYTYPE_SOP_STREAM0: cbRequired = sizeof(BOOL); break;
6227 case SVGA3D_QUERYTYPE_SOP_STREAM1: cbRequired = sizeof(BOOL); break;
6228 case SVGA3D_QUERYTYPE_SOP_STREAM2: cbRequired = sizeof(BOOL); break;
6229 case SVGA3D_QUERYTYPE_SOP_STREAM3: cbRequired = sizeof(BOOL); break;
6230 default:
6231 AssertFailedReturn(VERR_INVALID_STATE);
6232 }
6233
6234 ASSERT_GUEST_RETURN(cbData > cbRequired, VERR_INVALID_PARAMETER);
6235
6236 while (pDXDevice->pImmediateContext->GetData(pDXQuery->pQuery, pvData, cbRequired, 0) != S_OK)
6237 {
6238 }
6239
6240 *pcbOut = cbRequired;
6241 return VINF_SUCCESS;
6242}
6243
6244
6245static DECLCALLBACK(int) vmsvga3dBackDXReadbackQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
6246 SVGA3dQueryId queryId, void *pvData, uint32_t cbData, uint32_t *pcbOut)
6247{
6248 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6249 RT_NOREF(pBackend);
6250
6251 DXQUERY *pDXQuery = &pDXContext->pBackendDXContext->paQuery[queryId];
6252 int rc = dxReadbackQuery(pThisCC, pDXContext, queryId, pDXQuery, pvData, cbData, pcbOut);
6253 return rc;
6254}
6255
6256
6257static DECLCALLBACK(int) vmsvga3dBackDXSetPredication(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6258{
6259 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6260
6261 RT_NOREF(pBackend, pDXContext);
6262 AssertFailed(); /** @todo Implement */
6263 return VERR_NOT_IMPLEMENTED;
6264}
6265
6266
6267static DECLCALLBACK(int) vmsvga3dBackDXSetSOTargets(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t cSOTarget, SVGA3dSoTarget const *paSoTarget)
6268{
6269 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6270 RT_NOREF(pBackend);
6271
6272 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6273 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6274
6275 /* For each paSoTarget[i]:
6276 * If the stream outout buffer object does not exist then create it.
6277 * If the surface has been updated by the guest then update the buffer object.
6278 * Use SOSetTargets to set the buffers.
6279 */
6280
6281 ID3D11Buffer *paResource[SVGA3D_DX_MAX_SOTARGETS];
6282 UINT paOffset[SVGA3D_DX_MAX_SOTARGETS];
6283
6284 /* Always re-bind all 4 SO targets. They can be NULL. */
6285 for (uint32_t i = 0; i < SVGA3D_DX_MAX_SOTARGETS; ++i)
6286 {
6287 /* Get corresponding resource. Create the buffer if does not yet exist. */
6288 if (i < cSOTarget && paSoTarget[i].sid != SVGA_ID_INVALID)
6289 {
6290 PVMSVGA3DSURFACE pSurface;
6291 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, paSoTarget[i].sid, &pSurface);
6292 AssertRCReturn(rc, rc);
6293
6294 if (pSurface->pBackendSurface == NULL)
6295 {
6296 /* Create the resource. */
6297 rc = vmsvga3dBackSurfaceCreateSoBuffer(pThisCC, pDXContext, pSurface);
6298 AssertRCReturn(rc, rc);
6299 }
6300
6301 /** @todo How paSoTarget[i].sizeInBytes is used? Maybe when the buffer is created? */
6302 paResource[i] = pSurface->pBackendSurface->u.pBuffer;
6303 paOffset[i] = paSoTarget[i].offset;
6304 }
6305 else
6306 {
6307 paResource[i] = NULL;
6308 paOffset[i] = 0;
6309 }
6310 }
6311
6312 pDevice->pImmediateContext->SOSetTargets(SVGA3D_DX_MAX_SOTARGETS, paResource, paOffset);
6313
6314 pDXContext->pBackendDXContext->cSOTarget = cSOTarget;
6315
6316 return VINF_SUCCESS;
6317}
6318
6319
6320static DECLCALLBACK(int) vmsvga3dBackDXSetViewports(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t cViewport, SVGA3dViewport const *paViewport)
6321{
6322 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6323 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6324 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6325
6326 RT_NOREF(pBackend);
6327
6328 /* D3D11_VIEWPORT is identical to SVGA3dViewport. */
6329 D3D11_VIEWPORT *pViewports = (D3D11_VIEWPORT *)paViewport;
6330
6331 pDevice->pImmediateContext->RSSetViewports(cViewport, pViewports);
6332 return VINF_SUCCESS;
6333}
6334
6335
6336static DECLCALLBACK(int) vmsvga3dBackDXSetScissorRects(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t cRect, SVGASignedRect const *paRect)
6337{
6338 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6339 RT_NOREF(pBackend);
6340
6341 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6342 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6343
6344 /* D3D11_RECT is identical to SVGASignedRect. */
6345 D3D11_RECT *pRects = (D3D11_RECT *)paRect;
6346
6347 pDevice->pImmediateContext->RSSetScissorRects(cRect, pRects);
6348 return VINF_SUCCESS;
6349}
6350
6351
6352static DECLCALLBACK(int) vmsvga3dBackDXClearRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGA3dRGBAFloat const *pRGBA)
6353{
6354 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6355 RT_NOREF(pBackend);
6356
6357 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6358 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6359
6360 DXVIEW *pDXView = &pDXContext->pBackendDXContext->paRenderTargetView[renderTargetViewId];
6361 if (!pDXView->u.pRenderTargetView)
6362 {
6363//DEBUG_BREAKPOINT_TEST();
6364 /* (Re-)create the render target view, because a creation of a view is deferred until a draw or a clear call. */
6365 SVGACOTableDXRTViewEntry const *pEntry = &pDXContext->cot.paRTView[renderTargetViewId];
6366 int rc = dxDefineRenderTargetView(pThisCC, pDXContext, renderTargetViewId, pEntry);
6367 AssertRCReturn(rc, rc);
6368 }
6369 pDevice->pImmediateContext->ClearRenderTargetView(pDXView->u.pRenderTargetView, pRGBA->value);
6370 return VINF_SUCCESS;
6371}
6372
6373
6374static DECLCALLBACK(int) vmsvga3dBackDXClearDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, uint32_t flags, SVGA3dDepthStencilViewId depthStencilViewId, float depth, uint8_t stencil)
6375{
6376 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6377 RT_NOREF(pBackend);
6378
6379 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6380 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6381
6382 DXVIEW *pDXView = &pDXContext->pBackendDXContext->paDepthStencilView[depthStencilViewId];
6383 if (!pDXView->u.pDepthStencilView)
6384 {
6385//DEBUG_BREAKPOINT_TEST();
6386 /* (Re-)create the depth stencil view, because a creation of a view is deferred until a draw or a clear call. */
6387 SVGACOTableDXDSViewEntry const *pEntry = &pDXContext->cot.paDSView[depthStencilViewId];
6388 int rc = dxDefineDepthStencilView(pThisCC, pDXContext, depthStencilViewId, pEntry);
6389 AssertRCReturn(rc, rc);
6390 }
6391 pDevice->pImmediateContext->ClearDepthStencilView(pDXView->u.pDepthStencilView, flags, depth, stencil);
6392 return VINF_SUCCESS;
6393}
6394
6395
6396static DECLCALLBACK(int) vmsvga3dBackDXPredCopyRegion(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSurfaceId dstSid, uint32_t dstSubResource, SVGA3dSurfaceId srcSid, uint32_t srcSubResource, SVGA3dCopyBox const *pBox)
6397{
6398 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6399 RT_NOREF(pBackend);
6400
6401 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6402 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6403
6404 PVMSVGA3DSURFACE pSrcSurface;
6405 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, srcSid, &pSrcSurface);
6406 AssertRCReturn(rc, rc);
6407
6408 PVMSVGA3DSURFACE pDstSurface;
6409 rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, dstSid, &pDstSurface);
6410 AssertRCReturn(rc, rc);
6411
6412 if (pSrcSurface->pBackendSurface == NULL)
6413 {
6414 /* Create the resource. */
6415 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSrcSurface);
6416 AssertRCReturn(rc, rc);
6417 }
6418
6419 if (pDstSurface->pBackendSurface == NULL)
6420 {
6421 /* Create the resource. */
6422 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pDstSurface);
6423 AssertRCReturn(rc, rc);
6424 }
6425
6426 LogFunc(("cid %d: src cid %d%s -> dst cid %d%s\n",
6427 pDXContext->cid, pSrcSurface->idAssociatedContext,
6428 (pSrcSurface->surfaceFlags & SVGA3D_SURFACE_SCREENTARGET) ? " st" : "",
6429 pDstSurface->idAssociatedContext,
6430 (pDstSurface->surfaceFlags & SVGA3D_SURFACE_SCREENTARGET) ? " st" : ""));
6431
6432 /* Clip the box. */
6433 /** @todo Use [src|dst]SubResource to index p[Src|Dst]Surface->paMipmapLevels array directly. */
6434 uint32_t iSrcFace;
6435 uint32_t iSrcMipmap;
6436 vmsvga3dCalcMipmapAndFace(pSrcSurface->cLevels, srcSubResource, &iSrcMipmap, &iSrcFace);
6437
6438 uint32_t iDstFace;
6439 uint32_t iDstMipmap;
6440 vmsvga3dCalcMipmapAndFace(pDstSurface->cLevels, dstSubResource, &iDstMipmap, &iDstFace);
6441
6442 PVMSVGA3DMIPMAPLEVEL pSrcMipLevel;
6443 rc = vmsvga3dMipmapLevel(pSrcSurface, iSrcFace, iSrcMipmap, &pSrcMipLevel);
6444 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
6445
6446 PVMSVGA3DMIPMAPLEVEL pDstMipLevel;
6447 rc = vmsvga3dMipmapLevel(pDstSurface, iDstFace, iDstMipmap, &pDstMipLevel);
6448 ASSERT_GUEST_RETURN(RT_SUCCESS(rc), rc);
6449
6450 SVGA3dCopyBox clipBox = *pBox;
6451 vmsvgaR3ClipCopyBox(&pSrcMipLevel->mipmapSize, &pDstMipLevel->mipmapSize, &clipBox);
6452
6453 UINT DstSubresource = dstSubResource;
6454 UINT DstX = clipBox.x;
6455 UINT DstY = clipBox.y;
6456 UINT DstZ = clipBox.z;
6457
6458 UINT SrcSubresource = srcSubResource;
6459 D3D11_BOX SrcBox;
6460 SrcBox.left = clipBox.srcx;
6461 SrcBox.top = clipBox.srcy;
6462 SrcBox.front = clipBox.srcz;
6463 SrcBox.right = clipBox.srcx + clipBox.w;
6464 SrcBox.bottom = clipBox.srcy + clipBox.h;
6465 SrcBox.back = clipBox.srcz + clipBox.d;
6466
6467 ID3D11Resource *pDstResource;
6468 ID3D11Resource *pSrcResource;
6469
6470 pDstResource = dxResource(pThisCC->svga.p3dState, pDstSurface, pDXContext);
6471 pSrcResource = dxResource(pThisCC->svga.p3dState, pSrcSurface, pDXContext);
6472
6473 pDevice->pImmediateContext->CopySubresourceRegion(pDstResource, DstSubresource, DstX, DstY, DstZ,
6474 pSrcResource, SrcSubresource, &SrcBox);
6475
6476 pDstSurface->pBackendSurface->cidDrawing = pDXContext->cid;
6477 return VINF_SUCCESS;
6478}
6479
6480
6481static DECLCALLBACK(int) vmsvga3dBackDXPredCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6482{
6483 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6484
6485 RT_NOREF(pBackend, pDXContext);
6486 AssertFailed(); /** @todo Implement */
6487 return VERR_NOT_IMPLEMENTED;
6488}
6489
6490
6491static DECLCALLBACK(int) vmsvga3dBackDXPresentBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
6492{
6493 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6494
6495 RT_NOREF(pBackend, pDXContext);
6496 AssertFailed(); /** @todo Implement */
6497 return VERR_NOT_IMPLEMENTED;
6498}
6499
6500
6501static DECLCALLBACK(int) vmsvga3dBackDXGenMips(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId)
6502{
6503 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6504 RT_NOREF(pBackend);
6505
6506 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6507 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6508
6509 ID3D11ShaderResourceView *pShaderResourceView = pDXContext->pBackendDXContext->paShaderResourceView[shaderResourceViewId].u.pShaderResourceView;
6510 AssertReturn(pShaderResourceView, VERR_INVALID_STATE);
6511
6512 SVGACOTableDXSRViewEntry const *pSRViewEntry = dxGetShaderResourceViewEntry(pDXContext, shaderResourceViewId);
6513 AssertReturn(pSRViewEntry, VERR_INVALID_STATE);
6514
6515 uint32_t const sid = pSRViewEntry->sid;
6516
6517 PVMSVGA3DSURFACE pSurface;
6518 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, sid, &pSurface);
6519 AssertRCReturn(rc, rc);
6520 AssertReturn(pSurface->pBackendSurface, VERR_INVALID_STATE);
6521
6522 pDevice->pImmediateContext->GenerateMips(pShaderResourceView);
6523
6524 pSurface->pBackendSurface->cidDrawing = pDXContext->cid;
6525 return VINF_SUCCESS;
6526}
6527
6528
6529static int dxDefineShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId, SVGACOTableDXSRViewEntry const *pEntry)
6530{
6531 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
6532 PVMSVGA3DSURFACE pSurface;
6533 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
6534 AssertRCReturn(rc, rc);
6535
6536 ID3D11ShaderResourceView *pShaderResourceView;
6537 DXVIEW *pView = &pDXContext->pBackendDXContext->paShaderResourceView[shaderResourceViewId];
6538 Assert(pView->u.pView == NULL);
6539
6540 if (pSurface->pBackendSurface == NULL)
6541 {
6542 /* Create the actual texture. */
6543 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSurface);
6544 AssertRCReturn(rc, rc);
6545 }
6546
6547 HRESULT hr = dxShaderResourceViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pShaderResourceView);
6548 AssertReturn(SUCCEEDED(hr), VERR_INVALID_STATE);
6549
6550 return dxViewInit(pView, pSurface, pDXContext, shaderResourceViewId, VMSVGA3D_VIEWTYPE_SHADERRESOURCE, pShaderResourceView);
6551}
6552
6553
6554static DECLCALLBACK(int) vmsvga3dBackDXDefineShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId, SVGACOTableDXSRViewEntry const *pEntry)
6555{
6556 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6557 RT_NOREF(pBackend);
6558
6559 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6560 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6561
6562 /** @todo Probably not necessary because SRVs are defined in setupPipeline. */
6563 return dxDefineShaderResourceView(pThisCC, pDXContext, shaderResourceViewId, pEntry);
6564}
6565
6566
6567static DECLCALLBACK(int) vmsvga3dBackDXDestroyShaderResourceView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderResourceViewId shaderResourceViewId)
6568{
6569 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6570 RT_NOREF(pBackend);
6571
6572 return dxViewDestroy(&pDXContext->pBackendDXContext->paShaderResourceView[shaderResourceViewId]);
6573}
6574
6575
6576static int dxDefineRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGACOTableDXRTViewEntry const *pEntry)
6577{
6578 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
6579 PVMSVGA3DSURFACE pSurface;
6580 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
6581 AssertRCReturn(rc, rc);
6582
6583 DXVIEW *pView = &pDXContext->pBackendDXContext->paRenderTargetView[renderTargetViewId];
6584 Assert(pView->u.pView == NULL);
6585
6586 if (pSurface->pBackendSurface == NULL)
6587 {
6588 /* Create the actual texture. */
6589 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSurface);
6590 AssertRCReturn(rc, rc);
6591 }
6592
6593 ID3D11RenderTargetView *pRenderTargetView;
6594 HRESULT hr = dxRenderTargetViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pRenderTargetView);
6595 AssertReturn(SUCCEEDED(hr), VERR_INVALID_STATE);
6596
6597 return dxViewInit(pView, pSurface, pDXContext, renderTargetViewId, VMSVGA3D_VIEWTYPE_RENDERTARGET, pRenderTargetView);
6598}
6599
6600
6601static DECLCALLBACK(int) vmsvga3dBackDXDefineRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId, SVGACOTableDXRTViewEntry const *pEntry)
6602{
6603 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6604 RT_NOREF(pBackend);
6605
6606 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6607 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6608
6609 return dxDefineRenderTargetView(pThisCC, pDXContext, renderTargetViewId, pEntry);
6610}
6611
6612
6613static DECLCALLBACK(int) vmsvga3dBackDXDestroyRenderTargetView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRenderTargetViewId renderTargetViewId)
6614{
6615 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6616 RT_NOREF(pBackend);
6617
6618 return dxViewDestroy(&pDXContext->pBackendDXContext->paRenderTargetView[renderTargetViewId]);
6619}
6620
6621
6622static int dxDefineDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, SVGACOTableDXDSViewEntry const *pEntry)
6623{
6624 /* Get corresponding resource for pEntry->sid. Create the surface if does not yet exist. */
6625 PVMSVGA3DSURFACE pSurface;
6626 int rc = vmsvga3dSurfaceFromSid(pThisCC->svga.p3dState, pEntry->sid, &pSurface);
6627 AssertRCReturn(rc, rc);
6628
6629 DXVIEW *pView = &pDXContext->pBackendDXContext->paDepthStencilView[depthStencilViewId];
6630 Assert(pView->u.pView == NULL);
6631
6632 if ( pSurface->pBackendSurface != NULL
6633 && pDXContext->cid != pSurface->idAssociatedContext)
6634 {
6635 /* Supposed to be per context. Sometimes the guest reuses the texture in another context. */
6636 vmsvga3dBackSurfaceDestroy(pThisCC, pSurface);
6637 }
6638
6639 if (pSurface->pBackendSurface == NULL)
6640 {
6641 /* Create the actual texture. */
6642 rc = vmsvga3dBackSurfaceCreateTexture(pThisCC, pDXContext, pSurface);
6643 AssertRCReturn(rc, rc);
6644 }
6645
6646 ID3D11DepthStencilView *pDepthStencilView;
6647 HRESULT hr = dxDepthStencilViewCreate(pThisCC, pDXContext, pEntry, pSurface, &pDepthStencilView);
6648 AssertReturn(SUCCEEDED(hr), VERR_INVALID_STATE);
6649
6650 return dxViewInit(pView, pSurface, pDXContext, depthStencilViewId, VMSVGA3D_VIEWTYPE_DEPTHSTENCIL, pDepthStencilView);
6651}
6652
6653static DECLCALLBACK(int) vmsvga3dBackDXDefineDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId, SVGACOTableDXDSViewEntry const *pEntry)
6654{
6655 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6656 RT_NOREF(pBackend);
6657
6658 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6659 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6660
6661 return dxDefineDepthStencilView(pThisCC, pDXContext, depthStencilViewId, pEntry);
6662}
6663
6664
6665static DECLCALLBACK(int) vmsvga3dBackDXDestroyDepthStencilView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilViewId depthStencilViewId)
6666{
6667 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6668 RT_NOREF(pBackend);
6669
6670 return dxViewDestroy(&pDXContext->pBackendDXContext->paDepthStencilView[depthStencilViewId]);
6671}
6672
6673
6674static int dxDefineElementLayout(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId, SVGACOTableDXElementLayoutEntry const *pEntry)
6675{
6676 DXELEMENTLAYOUT *pDXElementLayout = &pDXContext->pBackendDXContext->paElementLayout[elementLayoutId];
6677 D3D_RELEASE(pDXElementLayout->pElementLayout);
6678
6679 /* Semantic name is not interpreted by D3D, therefore arbitrary names can be used
6680 * if they are consistent between the element layout and shader input signature.
6681 * "In general, data passed between pipeline stages is completely generic and is not uniquely
6682 * interpreted by the system; arbitrary semantics are allowed ..."
6683 *
6684 * However D3D runtime insists that "SemanticName string ("POSITIO1") cannot end with a number."
6685 *
6686 * System-Value semantics ("SV_*") between shaders require proper names of course.
6687 * But they are irrelevant for input attributes.
6688 */
6689 pDXElementLayout->cElementDesc = pEntry->numDescs;
6690 for (uint32_t i = 0; i < pEntry->numDescs; ++i)
6691 {
6692 D3D11_INPUT_ELEMENT_DESC *pDst = &pDXElementLayout->aElementDesc[i];
6693 SVGA3dInputElementDesc const *pSrc = &pEntry->descs[i];
6694 pDst->SemanticName = "ATTRIB";
6695 pDst->SemanticIndex = i; /// @todo 'pSrc->inputRegister' is unused, maybe it should somehow.
6696 pDst->Format = vmsvgaDXSurfaceFormat2Dxgi(pSrc->format);
6697 AssertReturn(pDst->Format != DXGI_FORMAT_UNKNOWN, VERR_NOT_IMPLEMENTED);
6698 pDst->InputSlot = pSrc->inputSlot;
6699 pDst->AlignedByteOffset = pSrc->alignedByteOffset;
6700 pDst->InputSlotClass = (D3D11_INPUT_CLASSIFICATION)pSrc->inputSlotClass;
6701 pDst->InstanceDataStepRate = pSrc->instanceDataStepRate;
6702 }
6703
6704 return VINF_SUCCESS;
6705}
6706
6707
6708static int dxDestroyElementLayout(DXELEMENTLAYOUT *pDXElementLayout)
6709{
6710 D3D_RELEASE(pDXElementLayout->pElementLayout);
6711 pDXElementLayout->cElementDesc = 0;
6712 RT_ZERO(pDXElementLayout->aElementDesc);
6713 return VINF_SUCCESS;
6714}
6715
6716
6717static DECLCALLBACK(int) vmsvga3dBackDXDefineElementLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId, SVGACOTableDXElementLayoutEntry const *pEntry)
6718{
6719 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6720 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6721 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6722
6723 RT_NOREF(pBackend);
6724
6725 /* Not much can be done here because ID3D11Device::CreateInputLayout requires
6726 * a pShaderBytecodeWithInputSignature which is not known at this moment.
6727 * InputLayout object will be created in setupPipeline.
6728 */
6729
6730 Assert(elementLayoutId == pEntry->elid);
6731
6732 return dxDefineElementLayout(pDXContext, elementLayoutId, pEntry);
6733}
6734
6735
6736static DECLCALLBACK(int) vmsvga3dBackDXDestroyElementLayout(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dElementLayoutId elementLayoutId)
6737{
6738 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6739 RT_NOREF(pBackend);
6740
6741 DXELEMENTLAYOUT *pDXElementLayout = &pDXContext->pBackendDXContext->paElementLayout[elementLayoutId];
6742 dxDestroyElementLayout(pDXElementLayout);
6743
6744 return VINF_SUCCESS;
6745}
6746
6747
6748static int dxDefineBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
6749 SVGA3dBlendStateId blendId, SVGACOTableDXBlendStateEntry const *pEntry)
6750{
6751 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6752 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6753
6754 HRESULT hr = dxBlendStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papBlendState[blendId]);
6755 if (SUCCEEDED(hr))
6756 return VINF_SUCCESS;
6757 return VERR_INVALID_STATE;
6758}
6759
6760
6761static DECLCALLBACK(int) vmsvga3dBackDXDefineBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext,
6762 SVGA3dBlendStateId blendId, SVGACOTableDXBlendStateEntry const *pEntry)
6763{
6764 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6765 RT_NOREF(pBackend);
6766
6767 return dxDefineBlendState(pThisCC, pDXContext, blendId, pEntry);
6768}
6769
6770
6771static DECLCALLBACK(int) vmsvga3dBackDXDestroyBlendState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dBlendStateId blendId)
6772{
6773 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6774 RT_NOREF(pBackend);
6775
6776 D3D_RELEASE(pDXContext->pBackendDXContext->papBlendState[blendId]);
6777 return VINF_SUCCESS;
6778}
6779
6780
6781static int dxDefineDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId, SVGACOTableDXDepthStencilEntry const *pEntry)
6782{
6783 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6784 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6785
6786 HRESULT hr = dxDepthStencilStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papDepthStencilState[depthStencilId]);
6787 if (SUCCEEDED(hr))
6788 return VINF_SUCCESS;
6789 return VERR_INVALID_STATE;
6790}
6791
6792
6793static DECLCALLBACK(int) vmsvga3dBackDXDefineDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId, SVGACOTableDXDepthStencilEntry const *pEntry)
6794{
6795 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6796 RT_NOREF(pBackend);
6797
6798 return dxDefineDepthStencilState(pThisCC, pDXContext, depthStencilId, pEntry);
6799}
6800
6801
6802static DECLCALLBACK(int) vmsvga3dBackDXDestroyDepthStencilState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dDepthStencilStateId depthStencilId)
6803{
6804 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6805 RT_NOREF(pBackend);
6806
6807 D3D_RELEASE(pDXContext->pBackendDXContext->papDepthStencilState[depthStencilId]);
6808 return VINF_SUCCESS;
6809}
6810
6811
6812static int dxDefineRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId, SVGACOTableDXRasterizerStateEntry const *pEntry)
6813{
6814 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6815 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6816
6817 HRESULT hr = dxRasterizerStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papRasterizerState[rasterizerId]);
6818 if (SUCCEEDED(hr))
6819 return VINF_SUCCESS;
6820 return VERR_INVALID_STATE;
6821}
6822
6823
6824static DECLCALLBACK(int) vmsvga3dBackDXDefineRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId, SVGACOTableDXRasterizerStateEntry const *pEntry)
6825{
6826 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6827 RT_NOREF(pBackend);
6828
6829 return dxDefineRasterizerState(pThisCC, pDXContext, rasterizerId, pEntry);
6830}
6831
6832
6833static DECLCALLBACK(int) vmsvga3dBackDXDestroyRasterizerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dRasterizerStateId rasterizerId)
6834{
6835 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6836 RT_NOREF(pBackend);
6837
6838 D3D_RELEASE(pDXContext->pBackendDXContext->papRasterizerState[rasterizerId]);
6839 return VINF_SUCCESS;
6840}
6841
6842
6843static int dxDefineSamplerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSamplerId samplerId, SVGACOTableDXSamplerEntry const *pEntry)
6844{
6845 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6846 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6847
6848 HRESULT hr = dxSamplerStateCreate(pDevice, pEntry, &pDXContext->pBackendDXContext->papSamplerState[samplerId]);
6849 if (SUCCEEDED(hr))
6850 return VINF_SUCCESS;
6851 return VERR_INVALID_STATE;
6852}
6853
6854
6855static DECLCALLBACK(int) vmsvga3dBackDXDefineSamplerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSamplerId samplerId, SVGACOTableDXSamplerEntry const *pEntry)
6856{
6857 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6858 RT_NOREF(pBackend);
6859
6860 return dxDefineSamplerState(pThisCC, pDXContext, samplerId, pEntry);
6861}
6862
6863
6864static DECLCALLBACK(int) vmsvga3dBackDXDestroySamplerState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dSamplerId samplerId)
6865{
6866 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6867 RT_NOREF(pBackend);
6868
6869 D3D_RELEASE(pDXContext->pBackendDXContext->papSamplerState[samplerId]);
6870 return VINF_SUCCESS;
6871}
6872
6873
6874static int dxDefineShader(PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, SVGACOTableDXShaderEntry const *pEntry)
6875{
6876 /** @todo A common approach for creation of COTable backend objects: runtime, empty DX COTable, live DX COTable. */
6877 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
6878 Assert(pDXShader->enmShaderType == SVGA3D_SHADERTYPE_INVALID);
6879
6880 /* Init the backend shader structure, if the shader has not been created yet. */
6881 pDXShader->enmShaderType = pEntry->type;
6882 pDXShader->pShader = NULL;
6883 pDXShader->soid = SVGA_ID_INVALID;
6884
6885 return VINF_SUCCESS;
6886}
6887
6888
6889static int dxDestroyShader(DXSHADER *pDXShader)
6890{
6891 pDXShader->enmShaderType = SVGA3D_SHADERTYPE_INVALID;
6892 D3D_RELEASE(pDXShader->pShader);
6893 RTMemFree(pDXShader->pvDXBC);
6894 pDXShader->pvDXBC = NULL;
6895 pDXShader->cbDXBC = 0;
6896 pDXShader->soid = SVGA_ID_INVALID;
6897 return VINF_SUCCESS;
6898}
6899
6900
6901static DECLCALLBACK(int) vmsvga3dBackDXDefineShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, SVGACOTableDXShaderEntry const *pEntry)
6902{
6903 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6904 RT_NOREF(pBackend);
6905
6906 return dxDefineShader(pDXContext, shaderId, pEntry);
6907}
6908
6909
6910static DECLCALLBACK(int) vmsvga3dBackDXDestroyShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId)
6911{
6912 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6913 RT_NOREF(pBackend);
6914
6915 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
6916 dxDestroyShader(pDXShader);
6917
6918 return VINF_SUCCESS;
6919}
6920
6921
6922static DECLCALLBACK(int) vmsvga3dBackDXBindShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dShaderId shaderId, DXShaderInfo const *pShaderInfo)
6923{
6924 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6925 DXDEVICE *pDevice = dxDeviceFromContext(pThisCC->svga.p3dState, pDXContext);
6926 AssertReturn(pDevice->pDevice, VERR_INVALID_STATE);
6927
6928 RT_NOREF(pBackend);
6929
6930 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[shaderId];
6931 if (pDXShader->pvDXBC)
6932 {
6933 /* New DXBC code and new shader must be created. */
6934 D3D_RELEASE(pDXShader->pShader);
6935 RTMemFree(pDXShader->pvDXBC);
6936 pDXShader->pvDXBC = NULL;
6937 pDXShader->cbDXBC = 0;
6938 }
6939
6940 pDXShader->shaderInfo = *pShaderInfo;
6941
6942 return VINF_SUCCESS;
6943}
6944
6945
6946static DECLCALLBACK(int) vmsvga3dBackDXDefineStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid, SVGACOTableDXStreamOutputEntry const *pEntry)
6947{
6948 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6949 RT_NOREF(pBackend);
6950
6951 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
6952 dxDestroyStreamOutput(pDXStreamOutput);
6953
6954 return dxDefineStreamOutput(pDXContext, soid, pEntry);
6955}
6956
6957
6958static DECLCALLBACK(int) vmsvga3dBackDXDestroyStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid)
6959{
6960 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6961 RT_NOREF(pBackend);
6962
6963 DXSTREAMOUTPUT *pDXStreamOutput = &pDXContext->pBackendDXContext->paStreamOutput[soid];
6964 dxDestroyStreamOutput(pDXStreamOutput);
6965
6966 return VINF_SUCCESS;
6967}
6968
6969
6970static DECLCALLBACK(int) vmsvga3dBackDXSetStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGA3dStreamOutputId soid)
6971{
6972 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
6973 RT_NOREF(pBackend, pDXContext, soid);
6974
6975 return VINF_SUCCESS;
6976}
6977
6978
6979static int dxCOTableRealloc(void **ppvCOTable, uint32_t *pcCOTable, uint32_t cbEntry, uint32_t cEntries, uint32_t cValidEntries)
6980{
6981 uint32_t const cCOTableCurrent = *pcCOTable;
6982
6983 if (*pcCOTable != cEntries)
6984 {
6985 /* Grow/shrink the array. */
6986 if (cEntries)
6987 {
6988 void *pvNew = RTMemRealloc(*ppvCOTable, cEntries * cbEntry);
6989 AssertReturn(pvNew, VERR_NO_MEMORY);
6990 *ppvCOTable = pvNew;
6991 }
6992 else
6993 {
6994 RTMemFree(*ppvCOTable);
6995 *ppvCOTable = NULL;
6996 }
6997
6998 *pcCOTable = cEntries;
6999 }
7000
7001 if (*ppvCOTable)
7002 {
7003 uint32_t const cEntriesToKeep = RT_MIN(cCOTableCurrent, cValidEntries);
7004 memset((uint8_t *)(*ppvCOTable) + cEntriesToKeep * cbEntry, 0, (cEntries - cEntriesToKeep) * cbEntry);
7005 }
7006
7007 return VINF_SUCCESS;
7008}
7009
7010static DECLCALLBACK(int) vmsvga3dBackDXSetCOTable(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, SVGACOTableType type, uint32_t cValidEntries)
7011{
7012 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7013 RT_NOREF(pBackend);
7014
7015 VMSVGA3DBACKENDDXCONTEXT *pBackendDXContext = pDXContext->pBackendDXContext;
7016
7017 int rc = VINF_SUCCESS;
7018
7019 /*
7020 * 1) Release current backend table, if exists;
7021 * 2) Reallocate memory for the new backend table;
7022 * 3) If cValidEntries is not zero, then re-define corresponding backend table elements.
7023 */
7024 switch (type)
7025 {
7026 case SVGA_COTABLE_RTVIEW:
7027 /* Clear current entries. */
7028 if (pBackendDXContext->paRenderTargetView)
7029 {
7030 for (uint32_t i = 0; i < pBackendDXContext->cRenderTargetView; ++i)
7031 {
7032 DXVIEW *pDXView = &pBackendDXContext->paRenderTargetView[i];
7033 if (i < cValidEntries)
7034 dxViewRemoveFromList(pDXView); /* Remove from list because DXVIEW array will be reallocated. */
7035 else
7036 dxViewDestroy(pDXView);
7037 }
7038 }
7039
7040 rc = dxCOTableRealloc((void **)&pBackendDXContext->paRenderTargetView, &pBackendDXContext->cRenderTargetView,
7041 sizeof(pBackendDXContext->paRenderTargetView[0]), pDXContext->cot.cRTView, cValidEntries);
7042 AssertRCBreak(rc);
7043
7044 for (uint32_t i = 0; i < cValidEntries; ++i)
7045 {
7046 SVGACOTableDXRTViewEntry const *pEntry = &pDXContext->cot.paRTView[i];
7047 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7048 continue; /* Skip uninitialized entry. */
7049
7050 /* Define views which were not defined yet in backend. */
7051 DXVIEW *pDXView = &pBackendDXContext->paRenderTargetView[i];
7052 /** @todo Verify that the pEntry content still corresponds to the view. */
7053 if (pDXView->u.pView)
7054 dxViewAddToList(pThisCC, pDXView);
7055 else if (pDXView->enmViewType == VMSVGA3D_VIEWTYPE_NONE)
7056 dxDefineRenderTargetView(pThisCC, pDXContext, i, pEntry);
7057 }
7058 break;
7059 case SVGA_COTABLE_DSVIEW:
7060 if (pBackendDXContext->paDepthStencilView)
7061 {
7062 for (uint32_t i = 0; i < pBackendDXContext->cDepthStencilView; ++i)
7063 {
7064 DXVIEW *pDXView = &pBackendDXContext->paDepthStencilView[i];
7065 if (i < cValidEntries)
7066 dxViewRemoveFromList(pDXView); /* Remove from list because DXVIEW array will be reallocated. */
7067 else
7068 dxViewDestroy(pDXView);
7069 }
7070 }
7071
7072 rc = dxCOTableRealloc((void **)&pBackendDXContext->paDepthStencilView, &pBackendDXContext->cDepthStencilView,
7073 sizeof(pBackendDXContext->paDepthStencilView[0]), pDXContext->cot.cDSView, cValidEntries);
7074 AssertRCBreak(rc);
7075
7076 for (uint32_t i = 0; i < cValidEntries; ++i)
7077 {
7078 SVGACOTableDXDSViewEntry const *pEntry = &pDXContext->cot.paDSView[i];
7079 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7080 continue; /* Skip uninitialized entry. */
7081
7082 /* Define views which were not defined yet in backend. */
7083 DXVIEW *pDXView = &pBackendDXContext->paDepthStencilView[i];
7084 /** @todo Verify that the pEntry content still corresponds to the view. */
7085 if (pDXView->u.pView)
7086 dxViewAddToList(pThisCC, pDXView);
7087 else if (pDXView->enmViewType == VMSVGA3D_VIEWTYPE_NONE)
7088 dxDefineDepthStencilView(pThisCC, pDXContext, i, pEntry);
7089 }
7090 break;
7091 case SVGA_COTABLE_SRVIEW:
7092 if (pBackendDXContext->paShaderResourceView)
7093 {
7094 for (uint32_t i = 0; i < pBackendDXContext->cShaderResourceView; ++i)
7095 {
7096 DXVIEW *pDXView = &pBackendDXContext->paShaderResourceView[i];
7097 if (i < cValidEntries)
7098 dxViewRemoveFromList(pDXView); /* Remove from list because DXVIEW array will be reallocated. */
7099 else
7100 dxViewDestroy(pDXView);
7101 }
7102 }
7103
7104 rc = dxCOTableRealloc((void **)&pBackendDXContext->paShaderResourceView, &pBackendDXContext->cShaderResourceView,
7105 sizeof(pBackendDXContext->paShaderResourceView[0]), pDXContext->cot.cSRView, cValidEntries);
7106 AssertRCBreak(rc);
7107
7108 for (uint32_t i = 0; i < cValidEntries; ++i)
7109 {
7110 SVGACOTableDXSRViewEntry const *pEntry = &pDXContext->cot.paSRView[i];
7111 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7112 continue; /* Skip uninitialized entry. */
7113
7114 /* Define views which were not defined yet in backend. */
7115 DXVIEW *pDXView = &pBackendDXContext->paShaderResourceView[i];
7116 /** @todo Verify that the pEntry content still corresponds to the view. */
7117 if (pDXView->u.pView)
7118 dxViewAddToList(pThisCC, pDXView);
7119 else if (pDXView->enmViewType == VMSVGA3D_VIEWTYPE_NONE)
7120 dxDefineShaderResourceView(pThisCC, pDXContext, i, pEntry);
7121 }
7122 break;
7123 case SVGA_COTABLE_ELEMENTLAYOUT:
7124 if (pBackendDXContext->paElementLayout)
7125 {
7126 for (uint32_t i = cValidEntries; i < pBackendDXContext->cElementLayout; ++i)
7127 D3D_RELEASE(pBackendDXContext->paElementLayout[i].pElementLayout);
7128 }
7129
7130 rc = dxCOTableRealloc((void **)&pBackendDXContext->paElementLayout, &pBackendDXContext->cElementLayout,
7131 sizeof(pBackendDXContext->paElementLayout[0]), pDXContext->cot.cElementLayout, cValidEntries);
7132 AssertRCBreak(rc);
7133
7134 for (uint32_t i = 0; i < cValidEntries; ++i)
7135 {
7136 SVGACOTableDXElementLayoutEntry const *pEntry = &pDXContext->cot.paElementLayout[i];
7137 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7138 continue; /* Skip uninitialized entry. */
7139
7140 dxDefineElementLayout(pDXContext, i, pEntry);
7141 }
7142 break;
7143 case SVGA_COTABLE_BLENDSTATE:
7144 if (pBackendDXContext->papBlendState)
7145 {
7146 for (uint32_t i = cValidEntries; i < pBackendDXContext->cBlendState; ++i)
7147 D3D_RELEASE(pBackendDXContext->papBlendState[i]);
7148 }
7149
7150 rc = dxCOTableRealloc((void **)&pBackendDXContext->papBlendState, &pBackendDXContext->cBlendState,
7151 sizeof(pBackendDXContext->papBlendState[0]), pDXContext->cot.cBlendState, cValidEntries);
7152 AssertRCBreak(rc);
7153
7154 for (uint32_t i = 0; i < cValidEntries; ++i)
7155 {
7156 SVGACOTableDXBlendStateEntry const *pEntry = &pDXContext->cot.paBlendState[i];
7157 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7158 continue; /* Skip uninitialized entry. */
7159
7160 dxDefineBlendState(pThisCC, pDXContext, i, pEntry);
7161 }
7162 break;
7163 case SVGA_COTABLE_DEPTHSTENCIL:
7164 if (pBackendDXContext->papDepthStencilState)
7165 {
7166 for (uint32_t i = cValidEntries; i < pBackendDXContext->cDepthStencilState; ++i)
7167 D3D_RELEASE(pBackendDXContext->papDepthStencilState[i]);
7168 }
7169
7170 rc = dxCOTableRealloc((void **)&pBackendDXContext->papDepthStencilState, &pBackendDXContext->cDepthStencilState,
7171 sizeof(pBackendDXContext->papDepthStencilState[0]), pDXContext->cot.cDepthStencil, cValidEntries);
7172 AssertRCBreak(rc);
7173
7174 for (uint32_t i = 0; i < cValidEntries; ++i)
7175 {
7176 SVGACOTableDXDepthStencilEntry const *pEntry = &pDXContext->cot.paDepthStencil[i];
7177 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7178 continue; /* Skip uninitialized entry. */
7179
7180 dxDefineDepthStencilState(pThisCC, pDXContext, i, pEntry);
7181 }
7182 break;
7183 case SVGA_COTABLE_RASTERIZERSTATE:
7184 if (pBackendDXContext->papRasterizerState)
7185 {
7186 for (uint32_t i = cValidEntries; i < pBackendDXContext->cRasterizerState; ++i)
7187 D3D_RELEASE(pBackendDXContext->papRasterizerState[i]);
7188 }
7189
7190 rc = dxCOTableRealloc((void **)&pBackendDXContext->papRasterizerState, &pBackendDXContext->cRasterizerState,
7191 sizeof(pBackendDXContext->papRasterizerState[0]), pDXContext->cot.cRasterizerState, cValidEntries);
7192 AssertRCBreak(rc);
7193
7194 for (uint32_t i = 0; i < cValidEntries; ++i)
7195 {
7196 SVGACOTableDXRasterizerStateEntry const *pEntry = &pDXContext->cot.paRasterizerState[i];
7197 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7198 continue; /* Skip uninitialized entry. */
7199
7200 dxDefineRasterizerState(pThisCC, pDXContext, i, pEntry);
7201 }
7202 break;
7203 case SVGA_COTABLE_SAMPLER:
7204 if (pBackendDXContext->papSamplerState)
7205 {
7206 for (uint32_t i = cValidEntries; i < pBackendDXContext->cSamplerState; ++i)
7207 D3D_RELEASE(pBackendDXContext->papSamplerState[i]);
7208 }
7209
7210 rc = dxCOTableRealloc((void **)&pBackendDXContext->papSamplerState, &pBackendDXContext->cSamplerState,
7211 sizeof(pBackendDXContext->papSamplerState[0]), pDXContext->cot.cSampler, cValidEntries);
7212 AssertRCBreak(rc);
7213
7214 for (uint32_t i = 0; i < cValidEntries; ++i)
7215 {
7216 SVGACOTableDXSamplerEntry const *pEntry = &pDXContext->cot.paSampler[i];
7217 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7218 continue; /* Skip uninitialized entry. */
7219
7220 dxDefineSamplerState(pThisCC, pDXContext, i, pEntry);
7221 }
7222 break;
7223 case SVGA_COTABLE_STREAMOUTPUT:
7224 if (pBackendDXContext->paStreamOutput)
7225 {
7226 for (uint32_t i = cValidEntries; i < pBackendDXContext->cStreamOutput; ++i)
7227 dxDestroyStreamOutput(&pBackendDXContext->paStreamOutput[i]);
7228 }
7229
7230 rc = dxCOTableRealloc((void **)&pBackendDXContext->paStreamOutput, &pBackendDXContext->cStreamOutput,
7231 sizeof(pBackendDXContext->paStreamOutput[0]), pDXContext->cot.cStreamOutput, cValidEntries);
7232 AssertRCBreak(rc);
7233
7234 for (uint32_t i = 0; i < cValidEntries; ++i)
7235 {
7236 SVGACOTableDXStreamOutputEntry const *pEntry = &pDXContext->cot.paStreamOutput[i];
7237 /** @todo The caller must verify the COTable content using same rules as when a new entry is defined. */
7238 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7239 continue; /* Skip uninitialized entry. */
7240
7241 dxDefineStreamOutput(pDXContext, i, pEntry);
7242 }
7243 break;
7244 case SVGA_COTABLE_DXQUERY:
7245 if (pBackendDXContext->paQuery)
7246 {
7247 /* Destroy the no longer used entries. */
7248 for (uint32_t i = cValidEntries; i < pBackendDXContext->cQuery; ++i)
7249 dxDestroyQuery(&pBackendDXContext->paQuery[i]);
7250 }
7251
7252 rc = dxCOTableRealloc((void **)&pBackendDXContext->paQuery, &pBackendDXContext->cQuery,
7253 sizeof(pBackendDXContext->paQuery[0]), pDXContext->cot.cQuery, cValidEntries);
7254 AssertRCBreak(rc);
7255
7256 for (uint32_t i = 0; i < cValidEntries; ++i)
7257 {
7258 SVGACOTableDXQueryEntry const *pEntry = &pDXContext->cot.paQuery[i];
7259 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7260 continue; /* Skip uninitialized entry. */
7261
7262 /* Define queries which were not defined yet in backend. */
7263 DXQUERY *pDXQuery = &pBackendDXContext->paQuery[i];
7264 if ( pEntry->type != SVGA3D_QUERYTYPE_INVALID
7265 && pDXQuery->pQuery == NULL)
7266 dxDefineQuery(pThisCC, pDXContext, i, pEntry);
7267 else
7268 Assert(pEntry->type == SVGA3D_QUERYTYPE_INVALID || pDXQuery->pQuery);
7269 }
7270 break;
7271 case SVGA_COTABLE_DXSHADER:
7272 if (pBackendDXContext->paShader)
7273 {
7274 /* Destroy the no longer used entries. */
7275 for (uint32_t i = cValidEntries; i < pBackendDXContext->cShader; ++i)
7276 dxDestroyShader(&pBackendDXContext->paShader[i]);
7277 }
7278
7279 rc = dxCOTableRealloc((void **)&pBackendDXContext->paShader, &pBackendDXContext->cShader,
7280 sizeof(pBackendDXContext->paShader[0]), pDXContext->cot.cShader, cValidEntries);
7281 AssertRCBreak(rc);
7282
7283 for (uint32_t i = 0; i < cValidEntries; ++i)
7284 {
7285 SVGACOTableDXShaderEntry const *pEntry = &pDXContext->cot.paShader[i];
7286 /** @todo The caller must verify the COTable content using same rules as when a new entry is defined. */
7287 if (ASMMemFirstNonZero(pEntry, sizeof(*pEntry)) == NULL)
7288 continue; /* Skip uninitialized entry. */
7289
7290 /* Define shaders which were not defined yet in backend. */
7291 DXSHADER *pDXShader = &pBackendDXContext->paShader[i];
7292 if ( pEntry->type != SVGA3D_SHADERTYPE_INVALID
7293 && pDXShader->enmShaderType == SVGA3D_SHADERTYPE_INVALID)
7294 dxDefineShader(pDXContext, i, pEntry);
7295 else
7296 Assert(pEntry->type == pDXShader->enmShaderType);
7297
7298 }
7299 break;
7300 case SVGA_COTABLE_UAVIEW:
7301 AssertFailed(); /** @todo Implement */
7302 break;
7303 case SVGA_COTABLE_MAX: break; /* Compiler warning */
7304 }
7305 return rc;
7306}
7307
7308
7309static DECLCALLBACK(int) vmsvga3dBackDXBufferCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7310{
7311 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7312
7313 RT_NOREF(pBackend, pDXContext);
7314 AssertFailed(); /** @todo Implement */
7315 return VERR_NOT_IMPLEMENTED;
7316}
7317
7318
7319static DECLCALLBACK(int) vmsvga3dBackDXSurfaceCopyAndReadback(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7320{
7321 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7322
7323 RT_NOREF(pBackend, pDXContext);
7324 AssertFailed(); /** @todo Implement */
7325 return VERR_NOT_IMPLEMENTED;
7326}
7327
7328
7329static DECLCALLBACK(int) vmsvga3dBackDXMoveQuery(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7330{
7331 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7332
7333 RT_NOREF(pBackend, pDXContext);
7334 AssertFailed(); /** @todo Implement */
7335 return VERR_NOT_IMPLEMENTED;
7336}
7337
7338
7339static DECLCALLBACK(int) vmsvga3dBackDXMobFence64(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7340{
7341 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7342
7343 RT_NOREF(pBackend, pDXContext);
7344 AssertFailed(); /** @todo Implement */
7345 return VERR_NOT_IMPLEMENTED;
7346}
7347
7348
7349static DECLCALLBACK(int) vmsvga3dBackDXBindAllShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7350{
7351 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7352
7353 RT_NOREF(pBackend, pDXContext);
7354 AssertFailed(); /** @todo Implement */
7355 return VERR_NOT_IMPLEMENTED;
7356}
7357
7358
7359static DECLCALLBACK(int) vmsvga3dBackDXHint(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7360{
7361 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7362
7363 RT_NOREF(pBackend, pDXContext);
7364 AssertFailed(); /** @todo Implement */
7365 return VERR_NOT_IMPLEMENTED;
7366}
7367
7368
7369static DECLCALLBACK(int) vmsvga3dBackDXBufferUpdate(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7370{
7371 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7372
7373 RT_NOREF(pBackend, pDXContext);
7374 AssertFailed(); /** @todo Implement */
7375 return VERR_NOT_IMPLEMENTED;
7376}
7377
7378
7379static DECLCALLBACK(int) vmsvga3dBackDXSetVSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7380{
7381 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7382
7383 RT_NOREF(pBackend, pDXContext);
7384 AssertFailed(); /** @todo Implement */
7385 return VERR_NOT_IMPLEMENTED;
7386}
7387
7388
7389static DECLCALLBACK(int) vmsvga3dBackDXSetPSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7390{
7391 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7392
7393 RT_NOREF(pBackend, pDXContext);
7394 AssertFailed(); /** @todo Implement */
7395 return VERR_NOT_IMPLEMENTED;
7396}
7397
7398
7399static DECLCALLBACK(int) vmsvga3dBackDXSetGSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7400{
7401 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7402
7403 RT_NOREF(pBackend, pDXContext);
7404 AssertFailed(); /** @todo Implement */
7405 return VERR_NOT_IMPLEMENTED;
7406}
7407
7408
7409static DECLCALLBACK(int) vmsvga3dBackDXSetHSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7410{
7411 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7412
7413 RT_NOREF(pBackend, pDXContext);
7414 AssertFailed(); /** @todo Implement */
7415 return VERR_NOT_IMPLEMENTED;
7416}
7417
7418
7419static DECLCALLBACK(int) vmsvga3dBackDXSetDSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7420{
7421 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7422
7423 RT_NOREF(pBackend, pDXContext);
7424 AssertFailed(); /** @todo Implement */
7425 return VERR_NOT_IMPLEMENTED;
7426}
7427
7428
7429static DECLCALLBACK(int) vmsvga3dBackDXSetCSConstantBufferOffset(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7430{
7431 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7432
7433 RT_NOREF(pBackend, pDXContext);
7434 AssertFailed(); /** @todo Implement */
7435 return VERR_NOT_IMPLEMENTED;
7436}
7437
7438
7439static DECLCALLBACK(int) vmsvga3dBackDXCondBindAllShader(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7440{
7441 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7442
7443 RT_NOREF(pBackend, pDXContext);
7444 AssertFailed(); /** @todo Implement */
7445 return VERR_NOT_IMPLEMENTED;
7446}
7447
7448
7449static DECLCALLBACK(int) vmsvga3dBackScreenCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7450{
7451 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7452
7453 RT_NOREF(pBackend, pDXContext);
7454 AssertFailed(); /** @todo Implement */
7455 return VERR_NOT_IMPLEMENTED;
7456}
7457
7458
7459static DECLCALLBACK(int) vmsvga3dBackGrowOTable(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7460{
7461 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7462
7463 RT_NOREF(pBackend, pDXContext);
7464 AssertFailed(); /** @todo Implement */
7465 return VERR_NOT_IMPLEMENTED;
7466}
7467
7468
7469static DECLCALLBACK(int) vmsvga3dBackDXGrowCOTable(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7470{
7471 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7472
7473 RT_NOREF(pBackend, pDXContext);
7474 AssertFailed(); /** @todo Implement */
7475 return VERR_NOT_IMPLEMENTED;
7476}
7477
7478
7479static DECLCALLBACK(int) vmsvga3dBackIntraSurfaceCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7480{
7481 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7482
7483 RT_NOREF(pBackend, pDXContext);
7484 AssertFailed(); /** @todo Implement */
7485 return VERR_NOT_IMPLEMENTED;
7486}
7487
7488
7489static DECLCALLBACK(int) vmsvga3dBackDefineGBSurface_v3(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7490{
7491 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7492
7493 RT_NOREF(pBackend, pDXContext);
7494 AssertFailed(); /** @todo Implement */
7495 return VERR_NOT_IMPLEMENTED;
7496}
7497
7498
7499static DECLCALLBACK(int) vmsvga3dBackDXResolveCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7500{
7501 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7502
7503 RT_NOREF(pBackend, pDXContext);
7504 AssertFailed(); /** @todo Implement */
7505 return VERR_NOT_IMPLEMENTED;
7506}
7507
7508
7509static DECLCALLBACK(int) vmsvga3dBackDXPredResolveCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7510{
7511 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7512
7513 RT_NOREF(pBackend, pDXContext);
7514 AssertFailed(); /** @todo Implement */
7515 return VERR_NOT_IMPLEMENTED;
7516}
7517
7518
7519static DECLCALLBACK(int) vmsvga3dBackDXPredConvertRegion(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7520{
7521 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7522
7523 RT_NOREF(pBackend, pDXContext);
7524 AssertFailed(); /** @todo Implement */
7525 return VERR_NOT_IMPLEMENTED;
7526}
7527
7528
7529static DECLCALLBACK(int) vmsvga3dBackDXPredConvert(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7530{
7531 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7532
7533 RT_NOREF(pBackend, pDXContext);
7534 AssertFailed(); /** @todo Implement */
7535 return VERR_NOT_IMPLEMENTED;
7536}
7537
7538
7539static DECLCALLBACK(int) vmsvga3dBackWholeSurfaceCopy(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7540{
7541 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7542
7543 RT_NOREF(pBackend, pDXContext);
7544 AssertFailed(); /** @todo Implement */
7545 return VERR_NOT_IMPLEMENTED;
7546}
7547
7548
7549static DECLCALLBACK(int) vmsvga3dBackDXDefineUAView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7550{
7551 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7552
7553 RT_NOREF(pBackend, pDXContext);
7554 AssertFailed(); /** @todo Implement */
7555 return VERR_NOT_IMPLEMENTED;
7556}
7557
7558
7559static DECLCALLBACK(int) vmsvga3dBackDXDestroyUAView(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7560{
7561 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7562
7563 RT_NOREF(pBackend, pDXContext);
7564 AssertFailed(); /** @todo Implement */
7565 return VERR_NOT_IMPLEMENTED;
7566}
7567
7568
7569static DECLCALLBACK(int) vmsvga3dBackDXClearUAViewUint(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7570{
7571 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7572
7573 RT_NOREF(pBackend, pDXContext);
7574 AssertFailed(); /** @todo Implement */
7575 return VERR_NOT_IMPLEMENTED;
7576}
7577
7578
7579static DECLCALLBACK(int) vmsvga3dBackDXClearUAViewFloat(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7580{
7581 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7582
7583 RT_NOREF(pBackend, pDXContext);
7584 AssertFailed(); /** @todo Implement */
7585 return VERR_NOT_IMPLEMENTED;
7586}
7587
7588
7589static DECLCALLBACK(int) vmsvga3dBackDXCopyStructureCount(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7590{
7591 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7592
7593 RT_NOREF(pBackend, pDXContext);
7594 AssertFailed(); /** @todo Implement */
7595 return VERR_NOT_IMPLEMENTED;
7596}
7597
7598
7599static DECLCALLBACK(int) vmsvga3dBackDXSetUAViews(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7600{
7601 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7602
7603 RT_NOREF(pBackend, pDXContext);
7604 AssertFailed(); /** @todo Implement */
7605 return VERR_NOT_IMPLEMENTED;
7606}
7607
7608
7609static DECLCALLBACK(int) vmsvga3dBackDXDrawIndexedInstancedIndirect(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7610{
7611 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7612
7613 RT_NOREF(pBackend, pDXContext);
7614 AssertFailed(); /** @todo Implement */
7615 return VERR_NOT_IMPLEMENTED;
7616}
7617
7618
7619static DECLCALLBACK(int) vmsvga3dBackDXDrawInstancedIndirect(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7620{
7621 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7622
7623 RT_NOREF(pBackend, pDXContext);
7624 AssertFailed(); /** @todo Implement */
7625 return VERR_NOT_IMPLEMENTED;
7626}
7627
7628
7629static DECLCALLBACK(int) vmsvga3dBackDXDispatch(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7630{
7631 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7632
7633 RT_NOREF(pBackend, pDXContext);
7634 AssertFailed(); /** @todo Implement */
7635 return VERR_NOT_IMPLEMENTED;
7636}
7637
7638
7639static DECLCALLBACK(int) vmsvga3dBackDXDispatchIndirect(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7640{
7641 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7642
7643 RT_NOREF(pBackend, pDXContext);
7644 AssertFailed(); /** @todo Implement */
7645 return VERR_NOT_IMPLEMENTED;
7646}
7647
7648
7649static DECLCALLBACK(int) vmsvga3dBackWriteZeroSurface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7650{
7651 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7652
7653 RT_NOREF(pBackend, pDXContext);
7654 AssertFailed(); /** @todo Implement */
7655 return VERR_NOT_IMPLEMENTED;
7656}
7657
7658
7659static DECLCALLBACK(int) vmsvga3dBackHintZeroSurface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7660{
7661 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7662
7663 RT_NOREF(pBackend, pDXContext);
7664 AssertFailed(); /** @todo Implement */
7665 return VERR_NOT_IMPLEMENTED;
7666}
7667
7668
7669static DECLCALLBACK(int) vmsvga3dBackDXTransferToBuffer(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7670{
7671 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7672
7673 RT_NOREF(pBackend, pDXContext);
7674 AssertFailed(); /** @todo Implement */
7675 return VERR_NOT_IMPLEMENTED;
7676}
7677
7678
7679static DECLCALLBACK(int) vmsvga3dBackDXSetStructureCount(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7680{
7681 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7682
7683 RT_NOREF(pBackend, pDXContext);
7684 AssertFailed(); /** @todo Implement */
7685 return VERR_NOT_IMPLEMENTED;
7686}
7687
7688
7689static DECLCALLBACK(int) vmsvga3dBackLogicOpsBitBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7690{
7691 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7692
7693 RT_NOREF(pBackend, pDXContext);
7694 AssertFailed(); /** @todo Implement */
7695 return VERR_NOT_IMPLEMENTED;
7696}
7697
7698
7699static DECLCALLBACK(int) vmsvga3dBackLogicOpsTransBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7700{
7701 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7702
7703 RT_NOREF(pBackend, pDXContext);
7704 AssertFailed(); /** @todo Implement */
7705 return VERR_NOT_IMPLEMENTED;
7706}
7707
7708
7709static DECLCALLBACK(int) vmsvga3dBackLogicOpsStretchBlt(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7710{
7711 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7712
7713 RT_NOREF(pBackend, pDXContext);
7714 AssertFailed(); /** @todo Implement */
7715 return VERR_NOT_IMPLEMENTED;
7716}
7717
7718
7719static DECLCALLBACK(int) vmsvga3dBackLogicOpsColorFill(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7720{
7721 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7722
7723 RT_NOREF(pBackend, pDXContext);
7724 AssertFailed(); /** @todo Implement */
7725 return VERR_NOT_IMPLEMENTED;
7726}
7727
7728
7729static DECLCALLBACK(int) vmsvga3dBackLogicOpsAlphaBlend(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7730{
7731 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7732
7733 RT_NOREF(pBackend, pDXContext);
7734 AssertFailed(); /** @todo Implement */
7735 return VERR_NOT_IMPLEMENTED;
7736}
7737
7738
7739static DECLCALLBACK(int) vmsvga3dBackLogicOpsClearTypeBlend(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7740{
7741 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7742
7743 RT_NOREF(pBackend, pDXContext);
7744 AssertFailed(); /** @todo Implement */
7745 return VERR_NOT_IMPLEMENTED;
7746}
7747
7748
7749static DECLCALLBACK(int) vmsvga3dBackDefineGBSurface_v4(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7750{
7751 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7752
7753 RT_NOREF(pBackend, pDXContext);
7754 AssertFailed(); /** @todo Implement */
7755 return VERR_NOT_IMPLEMENTED;
7756}
7757
7758
7759static DECLCALLBACK(int) vmsvga3dBackDXSetCSUAViews(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7760{
7761 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7762
7763 RT_NOREF(pBackend, pDXContext);
7764 AssertFailed(); /** @todo Implement */
7765 return VERR_NOT_IMPLEMENTED;
7766}
7767
7768
7769static DECLCALLBACK(int) vmsvga3dBackDXSetMinLOD(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7770{
7771 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7772
7773 RT_NOREF(pBackend, pDXContext);
7774 AssertFailed(); /** @todo Implement */
7775 return VERR_NOT_IMPLEMENTED;
7776}
7777
7778
7779static DECLCALLBACK(int) vmsvga3dBackDXDefineStreamOutputWithMob(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7780{
7781 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7782
7783 RT_NOREF(pBackend, pDXContext);
7784 AssertFailed(); /** @todo Implement */
7785 return VERR_NOT_IMPLEMENTED;
7786}
7787
7788
7789static DECLCALLBACK(int) vmsvga3dBackDXSetShaderIface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7790{
7791 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7792
7793 RT_NOREF(pBackend, pDXContext);
7794 AssertFailed(); /** @todo Implement */
7795 return VERR_NOT_IMPLEMENTED;
7796}
7797
7798
7799static DECLCALLBACK(int) vmsvga3dBackDXBindStreamOutput(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7800{
7801 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7802
7803 RT_NOREF(pBackend, pDXContext);
7804 AssertFailed(); /** @todo Implement */
7805 return VERR_NOT_IMPLEMENTED;
7806}
7807
7808
7809static DECLCALLBACK(int) vmsvga3dBackSurfaceStretchBltNonMSToMS(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7810{
7811 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7812
7813 RT_NOREF(pBackend, pDXContext);
7814 AssertFailed(); /** @todo Implement */
7815 return VERR_NOT_IMPLEMENTED;
7816}
7817
7818
7819static DECLCALLBACK(int) vmsvga3dBackDXBindShaderIface(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext)
7820{
7821 PVMSVGA3DBACKEND pBackend = pThisCC->svga.p3dState->pBackend;
7822
7823 RT_NOREF(pBackend, pDXContext);
7824 AssertFailed(); /** @todo Implement */
7825 return VERR_NOT_IMPLEMENTED;
7826}
7827
7828
7829static DECLCALLBACK(int) vmsvga3dBackDXLoadState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PCPDMDEVHLPR3 pHlp, PSSMHANDLE pSSM)
7830{
7831 RT_NOREF(pThisCC);
7832 uint32_t u32;
7833 int rc;
7834
7835 rc = pHlp->pfnSSMGetU32(pSSM, &u32);
7836 AssertLogRelRCReturn(rc, rc);
7837 AssertLogRelRCReturn(u32 == pDXContext->pBackendDXContext->cShader, VERR_INVALID_STATE);
7838
7839 for (uint32_t i = 0; i < pDXContext->pBackendDXContext->cShader; ++i)
7840 {
7841 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[i];
7842
7843 rc = pHlp->pfnSSMGetU32(pSSM, &u32);
7844 AssertLogRelRCReturn(rc, rc);
7845 AssertLogRelReturn((SVGA3dShaderType)u32 == pDXShader->enmShaderType, VERR_INVALID_STATE);
7846
7847 if (pDXShader->enmShaderType == SVGA3D_SHADERTYPE_INVALID)
7848 continue;
7849
7850 pHlp->pfnSSMGetU32(pSSM, &pDXShader->soid);
7851
7852 pHlp->pfnSSMGetU32(pSSM, &u32);
7853 pDXShader->shaderInfo.enmProgramType = (VGPU10_PROGRAM_TYPE)u32;
7854
7855 rc = pHlp->pfnSSMGetU32(pSSM, &pDXShader->shaderInfo.cbBytecode);
7856 AssertLogRelRCReturn(rc, rc);
7857 AssertLogRelReturn(pDXShader->shaderInfo.cbBytecode <= 2 * SVGA3D_MAX_SHADER_MEMORY_BYTES, VERR_INVALID_STATE);
7858
7859 if (pDXShader->shaderInfo.cbBytecode)
7860 {
7861 pDXShader->shaderInfo.pvBytecode = RTMemAlloc(pDXShader->shaderInfo.cbBytecode);
7862 AssertPtrReturn(pDXShader->shaderInfo.pvBytecode, VERR_NO_MEMORY);
7863 pHlp->pfnSSMGetMem(pSSM, pDXShader->shaderInfo.pvBytecode, pDXShader->shaderInfo.cbBytecode);
7864 }
7865
7866 rc = pHlp->pfnSSMGetU32(pSSM, &pDXShader->shaderInfo.cInputSignature);
7867 AssertLogRelRCReturn(rc, rc);
7868 AssertLogRelReturn(pDXShader->shaderInfo.cInputSignature <= 32, VERR_INVALID_STATE);
7869 if (pDXShader->shaderInfo.cInputSignature)
7870 pHlp->pfnSSMGetMem(pSSM, pDXShader->shaderInfo.aInputSignature, pDXShader->shaderInfo.cInputSignature * sizeof(SVGA3dDXSignatureEntry));
7871
7872 rc = pHlp->pfnSSMGetU32(pSSM, &pDXShader->shaderInfo.cOutputSignature);
7873 AssertLogRelRCReturn(rc, rc);
7874 AssertLogRelReturn(pDXShader->shaderInfo.cOutputSignature <= 32, VERR_INVALID_STATE);
7875 if (pDXShader->shaderInfo.cOutputSignature)
7876 pHlp->pfnSSMGetMem(pSSM, pDXShader->shaderInfo.aOutputSignature, pDXShader->shaderInfo.cOutputSignature * sizeof(SVGA3dDXSignatureEntry));
7877
7878 rc = pHlp->pfnSSMGetU32(pSSM, &pDXShader->shaderInfo.cPatchConstantSignature);
7879 AssertLogRelRCReturn(rc, rc);
7880 AssertLogRelReturn(pDXShader->shaderInfo.cPatchConstantSignature <= 32, VERR_INVALID_STATE);
7881 if (pDXShader->shaderInfo.cPatchConstantSignature)
7882 pHlp->pfnSSMGetMem(pSSM, pDXShader->shaderInfo.aPatchConstantSignature, pDXShader->shaderInfo.cPatchConstantSignature * sizeof(SVGA3dDXSignatureEntry));
7883
7884 rc = pHlp->pfnSSMGetU32(pSSM, &pDXShader->shaderInfo.cDclResource);
7885 AssertLogRelRCReturn(rc, rc);
7886 AssertLogRelReturn(pDXShader->shaderInfo.cDclResource <= SVGA3D_DX_MAX_SRVIEWS, VERR_INVALID_STATE);
7887 if (pDXShader->shaderInfo.cDclResource)
7888 pHlp->pfnSSMGetMem(pSSM, pDXShader->shaderInfo.aOffDclResource, pDXShader->shaderInfo.cDclResource * sizeof(uint32_t));
7889 }
7890
7891 rc = pHlp->pfnSSMGetU32(pSSM, &pDXContext->pBackendDXContext->cSOTarget);
7892 AssertLogRelRCReturn(rc, rc);
7893
7894 return VINF_SUCCESS;
7895}
7896
7897
7898static DECLCALLBACK(int) vmsvga3dBackDXSaveState(PVGASTATECC pThisCC, PVMSVGA3DDXCONTEXT pDXContext, PCPDMDEVHLPR3 pHlp, PSSMHANDLE pSSM)
7899{
7900 RT_NOREF(pThisCC);
7901 int rc;
7902
7903 pHlp->pfnSSMPutU32(pSSM, pDXContext->pBackendDXContext->cShader);
7904 for (uint32_t i = 0; i < pDXContext->pBackendDXContext->cShader; ++i)
7905 {
7906 DXSHADER *pDXShader = &pDXContext->pBackendDXContext->paShader[i];
7907
7908 pHlp->pfnSSMPutU32(pSSM, (uint32_t)pDXShader->enmShaderType);
7909 if (pDXShader->enmShaderType == SVGA3D_SHADERTYPE_INVALID)
7910 continue;
7911
7912 pHlp->pfnSSMPutU32(pSSM, pDXShader->soid);
7913
7914 pHlp->pfnSSMPutU32(pSSM, (uint32_t)pDXShader->shaderInfo.enmProgramType);
7915
7916 pHlp->pfnSSMPutU32(pSSM, pDXShader->shaderInfo.cbBytecode);
7917 if (pDXShader->shaderInfo.cbBytecode)
7918 pHlp->pfnSSMPutMem(pSSM, pDXShader->shaderInfo.pvBytecode, pDXShader->shaderInfo.cbBytecode);
7919
7920 pHlp->pfnSSMPutU32(pSSM, pDXShader->shaderInfo.cInputSignature);
7921 if (pDXShader->shaderInfo.cInputSignature)
7922 pHlp->pfnSSMPutMem(pSSM, pDXShader->shaderInfo.aInputSignature, pDXShader->shaderInfo.cInputSignature * sizeof(SVGA3dDXSignatureEntry));
7923
7924 pHlp->pfnSSMPutU32(pSSM, pDXShader->shaderInfo.cOutputSignature);
7925 if (pDXShader->shaderInfo.cOutputSignature)
7926 pHlp->pfnSSMPutMem(pSSM, pDXShader->shaderInfo.aOutputSignature, pDXShader->shaderInfo.cOutputSignature * sizeof(SVGA3dDXSignatureEntry));
7927
7928 pHlp->pfnSSMPutU32(pSSM, pDXShader->shaderInfo.cPatchConstantSignature);
7929 if (pDXShader->shaderInfo.cPatchConstantSignature)
7930 pHlp->pfnSSMPutMem(pSSM, pDXShader->shaderInfo.aPatchConstantSignature, pDXShader->shaderInfo.cPatchConstantSignature * sizeof(SVGA3dDXSignatureEntry));
7931
7932 pHlp->pfnSSMPutU32(pSSM, pDXShader->shaderInfo.cDclResource);
7933 if (pDXShader->shaderInfo.cDclResource)
7934 pHlp->pfnSSMPutMem(pSSM, pDXShader->shaderInfo.aOffDclResource, pDXShader->shaderInfo.cDclResource * sizeof(uint32_t));
7935 }
7936 rc = pHlp->pfnSSMPutU32(pSSM, pDXContext->pBackendDXContext->cSOTarget);
7937 AssertLogRelRCReturn(rc, rc);
7938
7939 return VINF_SUCCESS;
7940}
7941
7942
7943static DECLCALLBACK(int) vmsvga3dBackQueryInterface(PVGASTATECC pThisCC, char const *pszInterfaceName, void *pvInterfaceFuncs, size_t cbInterfaceFuncs)
7944{
7945 RT_NOREF(pThisCC);
7946
7947 int rc = VINF_SUCCESS;
7948 if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_DX) == 0)
7949 {
7950 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSDX))
7951 {
7952 if (pvInterfaceFuncs)
7953 {
7954 VMSVGA3DBACKENDFUNCSDX *p = (VMSVGA3DBACKENDFUNCSDX *)pvInterfaceFuncs;
7955 p->pfnDXSaveState = vmsvga3dBackDXSaveState;
7956 p->pfnDXLoadState = vmsvga3dBackDXLoadState;
7957 p->pfnDXDefineContext = vmsvga3dBackDXDefineContext;
7958 p->pfnDXDestroyContext = vmsvga3dBackDXDestroyContext;
7959 p->pfnDXBindContext = vmsvga3dBackDXBindContext;
7960 p->pfnDXSwitchContext = vmsvga3dBackDXSwitchContext;
7961 p->pfnDXReadbackContext = vmsvga3dBackDXReadbackContext;
7962 p->pfnDXInvalidateContext = vmsvga3dBackDXInvalidateContext;
7963 p->pfnDXSetSingleConstantBuffer = vmsvga3dBackDXSetSingleConstantBuffer;
7964 p->pfnDXSetShaderResources = vmsvga3dBackDXSetShaderResources;
7965 p->pfnDXSetShader = vmsvga3dBackDXSetShader;
7966 p->pfnDXSetSamplers = vmsvga3dBackDXSetSamplers;
7967 p->pfnDXDraw = vmsvga3dBackDXDraw;
7968 p->pfnDXDrawIndexed = vmsvga3dBackDXDrawIndexed;
7969 p->pfnDXDrawInstanced = vmsvga3dBackDXDrawInstanced;
7970 p->pfnDXDrawIndexedInstanced = vmsvga3dBackDXDrawIndexedInstanced;
7971 p->pfnDXDrawAuto = vmsvga3dBackDXDrawAuto;
7972 p->pfnDXSetInputLayout = vmsvga3dBackDXSetInputLayout;
7973 p->pfnDXSetVertexBuffers = vmsvga3dBackDXSetVertexBuffers;
7974 p->pfnDXSetIndexBuffer = vmsvga3dBackDXSetIndexBuffer;
7975 p->pfnDXSetTopology = vmsvga3dBackDXSetTopology;
7976 p->pfnDXSetRenderTargets = vmsvga3dBackDXSetRenderTargets;
7977 p->pfnDXSetBlendState = vmsvga3dBackDXSetBlendState;
7978 p->pfnDXSetDepthStencilState = vmsvga3dBackDXSetDepthStencilState;
7979 p->pfnDXSetRasterizerState = vmsvga3dBackDXSetRasterizerState;
7980 p->pfnDXDefineQuery = vmsvga3dBackDXDefineQuery;
7981 p->pfnDXDestroyQuery = vmsvga3dBackDXDestroyQuery;
7982 p->pfnDXBindQuery = vmsvga3dBackDXBindQuery;
7983 p->pfnDXBeginQuery = vmsvga3dBackDXBeginQuery;
7984 p->pfnDXEndQuery = vmsvga3dBackDXEndQuery;
7985 p->pfnDXReadbackQuery = vmsvga3dBackDXReadbackQuery;
7986 p->pfnDXSetPredication = vmsvga3dBackDXSetPredication;
7987 p->pfnDXSetSOTargets = vmsvga3dBackDXSetSOTargets;
7988 p->pfnDXSetViewports = vmsvga3dBackDXSetViewports;
7989 p->pfnDXSetScissorRects = vmsvga3dBackDXSetScissorRects;
7990 p->pfnDXClearRenderTargetView = vmsvga3dBackDXClearRenderTargetView;
7991 p->pfnDXClearDepthStencilView = vmsvga3dBackDXClearDepthStencilView;
7992 p->pfnDXPredCopyRegion = vmsvga3dBackDXPredCopyRegion;
7993 p->pfnDXPredCopy = vmsvga3dBackDXPredCopy;
7994 p->pfnDXPresentBlt = vmsvga3dBackDXPresentBlt;
7995 p->pfnDXGenMips = vmsvga3dBackDXGenMips;
7996 p->pfnDXDefineShaderResourceView = vmsvga3dBackDXDefineShaderResourceView;
7997 p->pfnDXDestroyShaderResourceView = vmsvga3dBackDXDestroyShaderResourceView;
7998 p->pfnDXDefineRenderTargetView = vmsvga3dBackDXDefineRenderTargetView;
7999 p->pfnDXDestroyRenderTargetView = vmsvga3dBackDXDestroyRenderTargetView;
8000 p->pfnDXDefineDepthStencilView = vmsvga3dBackDXDefineDepthStencilView;
8001 p->pfnDXDestroyDepthStencilView = vmsvga3dBackDXDestroyDepthStencilView;
8002 p->pfnDXDefineElementLayout = vmsvga3dBackDXDefineElementLayout;
8003 p->pfnDXDestroyElementLayout = vmsvga3dBackDXDestroyElementLayout;
8004 p->pfnDXDefineBlendState = vmsvga3dBackDXDefineBlendState;
8005 p->pfnDXDestroyBlendState = vmsvga3dBackDXDestroyBlendState;
8006 p->pfnDXDefineDepthStencilState = vmsvga3dBackDXDefineDepthStencilState;
8007 p->pfnDXDestroyDepthStencilState = vmsvga3dBackDXDestroyDepthStencilState;
8008 p->pfnDXDefineRasterizerState = vmsvga3dBackDXDefineRasterizerState;
8009 p->pfnDXDestroyRasterizerState = vmsvga3dBackDXDestroyRasterizerState;
8010 p->pfnDXDefineSamplerState = vmsvga3dBackDXDefineSamplerState;
8011 p->pfnDXDestroySamplerState = vmsvga3dBackDXDestroySamplerState;
8012 p->pfnDXDefineShader = vmsvga3dBackDXDefineShader;
8013 p->pfnDXDestroyShader = vmsvga3dBackDXDestroyShader;
8014 p->pfnDXBindShader = vmsvga3dBackDXBindShader;
8015 p->pfnDXDefineStreamOutput = vmsvga3dBackDXDefineStreamOutput;
8016 p->pfnDXDestroyStreamOutput = vmsvga3dBackDXDestroyStreamOutput;
8017 p->pfnDXSetStreamOutput = vmsvga3dBackDXSetStreamOutput;
8018 p->pfnDXSetCOTable = vmsvga3dBackDXSetCOTable;
8019 p->pfnDXBufferCopy = vmsvga3dBackDXBufferCopy;
8020 p->pfnDXSurfaceCopyAndReadback = vmsvga3dBackDXSurfaceCopyAndReadback;
8021 p->pfnDXMoveQuery = vmsvga3dBackDXMoveQuery;
8022 p->pfnDXMobFence64 = vmsvga3dBackDXMobFence64;
8023 p->pfnDXBindAllShader = vmsvga3dBackDXBindAllShader;
8024 p->pfnDXHint = vmsvga3dBackDXHint;
8025 p->pfnDXBufferUpdate = vmsvga3dBackDXBufferUpdate;
8026 p->pfnDXSetVSConstantBufferOffset = vmsvga3dBackDXSetVSConstantBufferOffset;
8027 p->pfnDXSetPSConstantBufferOffset = vmsvga3dBackDXSetPSConstantBufferOffset;
8028 p->pfnDXSetGSConstantBufferOffset = vmsvga3dBackDXSetGSConstantBufferOffset;
8029 p->pfnDXSetHSConstantBufferOffset = vmsvga3dBackDXSetHSConstantBufferOffset;
8030 p->pfnDXSetDSConstantBufferOffset = vmsvga3dBackDXSetDSConstantBufferOffset;
8031 p->pfnDXSetCSConstantBufferOffset = vmsvga3dBackDXSetCSConstantBufferOffset;
8032 p->pfnDXCondBindAllShader = vmsvga3dBackDXCondBindAllShader;
8033 p->pfnScreenCopy = vmsvga3dBackScreenCopy;
8034 p->pfnGrowOTable = vmsvga3dBackGrowOTable;
8035 p->pfnDXGrowCOTable = vmsvga3dBackDXGrowCOTable;
8036 p->pfnIntraSurfaceCopy = vmsvga3dBackIntraSurfaceCopy;
8037 p->pfnDefineGBSurface_v3 = vmsvga3dBackDefineGBSurface_v3;
8038 p->pfnDXResolveCopy = vmsvga3dBackDXResolveCopy;
8039 p->pfnDXPredResolveCopy = vmsvga3dBackDXPredResolveCopy;
8040 p->pfnDXPredConvertRegion = vmsvga3dBackDXPredConvertRegion;
8041 p->pfnDXPredConvert = vmsvga3dBackDXPredConvert;
8042 p->pfnWholeSurfaceCopy = vmsvga3dBackWholeSurfaceCopy;
8043 p->pfnDXDefineUAView = vmsvga3dBackDXDefineUAView;
8044 p->pfnDXDestroyUAView = vmsvga3dBackDXDestroyUAView;
8045 p->pfnDXClearUAViewUint = vmsvga3dBackDXClearUAViewUint;
8046 p->pfnDXClearUAViewFloat = vmsvga3dBackDXClearUAViewFloat;
8047 p->pfnDXCopyStructureCount = vmsvga3dBackDXCopyStructureCount;
8048 p->pfnDXSetUAViews = vmsvga3dBackDXSetUAViews;
8049 p->pfnDXDrawIndexedInstancedIndirect = vmsvga3dBackDXDrawIndexedInstancedIndirect;
8050 p->pfnDXDrawInstancedIndirect = vmsvga3dBackDXDrawInstancedIndirect;
8051 p->pfnDXDispatch = vmsvga3dBackDXDispatch;
8052 p->pfnDXDispatchIndirect = vmsvga3dBackDXDispatchIndirect;
8053 p->pfnWriteZeroSurface = vmsvga3dBackWriteZeroSurface;
8054 p->pfnHintZeroSurface = vmsvga3dBackHintZeroSurface;
8055 p->pfnDXTransferToBuffer = vmsvga3dBackDXTransferToBuffer;
8056 p->pfnDXSetStructureCount = vmsvga3dBackDXSetStructureCount;
8057 p->pfnLogicOpsBitBlt = vmsvga3dBackLogicOpsBitBlt;
8058 p->pfnLogicOpsTransBlt = vmsvga3dBackLogicOpsTransBlt;
8059 p->pfnLogicOpsStretchBlt = vmsvga3dBackLogicOpsStretchBlt;
8060 p->pfnLogicOpsColorFill = vmsvga3dBackLogicOpsColorFill;
8061 p->pfnLogicOpsAlphaBlend = vmsvga3dBackLogicOpsAlphaBlend;
8062 p->pfnLogicOpsClearTypeBlend = vmsvga3dBackLogicOpsClearTypeBlend;
8063 p->pfnDefineGBSurface_v4 = vmsvga3dBackDefineGBSurface_v4;
8064 p->pfnDXSetCSUAViews = vmsvga3dBackDXSetCSUAViews;
8065 p->pfnDXSetMinLOD = vmsvga3dBackDXSetMinLOD;
8066 p->pfnDXDefineStreamOutputWithMob = vmsvga3dBackDXDefineStreamOutputWithMob;
8067 p->pfnDXSetShaderIface = vmsvga3dBackDXSetShaderIface;
8068 p->pfnDXBindStreamOutput = vmsvga3dBackDXBindStreamOutput;
8069 p->pfnSurfaceStretchBltNonMSToMS = vmsvga3dBackSurfaceStretchBltNonMSToMS;
8070 p->pfnDXBindShaderIface = vmsvga3dBackDXBindShaderIface;
8071 }
8072 }
8073 else
8074 {
8075 AssertFailed();
8076 rc = VERR_INVALID_PARAMETER;
8077 }
8078 }
8079 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_MAP) == 0)
8080 {
8081 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSMAP))
8082 {
8083 if (pvInterfaceFuncs)
8084 {
8085 VMSVGA3DBACKENDFUNCSMAP *p = (VMSVGA3DBACKENDFUNCSMAP *)pvInterfaceFuncs;
8086 p->pfnSurfaceMap = vmsvga3dBackSurfaceMap;
8087 p->pfnSurfaceUnmap = vmsvga3dBackSurfaceUnmap;
8088 }
8089 }
8090 else
8091 {
8092 AssertFailed();
8093 rc = VERR_INVALID_PARAMETER;
8094 }
8095 }
8096 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_GBO) == 0)
8097 {
8098 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCSGBO))
8099 {
8100 if (pvInterfaceFuncs)
8101 {
8102 VMSVGA3DBACKENDFUNCSGBO *p = (VMSVGA3DBACKENDFUNCSGBO *)pvInterfaceFuncs;
8103 p->pfnScreenTargetBind = vmsvga3dScreenTargetBind;
8104 p->pfnScreenTargetUpdate = vmsvga3dScreenTargetUpdate;
8105 }
8106 }
8107 else
8108 {
8109 AssertFailed();
8110 rc = VERR_INVALID_PARAMETER;
8111 }
8112 }
8113 else if (RTStrCmp(pszInterfaceName, VMSVGA3D_BACKEND_INTERFACE_NAME_3D) == 0)
8114 {
8115 if (cbInterfaceFuncs == sizeof(VMSVGA3DBACKENDFUNCS3D))
8116 {
8117 if (pvInterfaceFuncs)
8118 {
8119 VMSVGA3DBACKENDFUNCS3D *p = (VMSVGA3DBACKENDFUNCS3D *)pvInterfaceFuncs;
8120 p->pfnInit = vmsvga3dBackInit;
8121 p->pfnPowerOn = vmsvga3dBackPowerOn;
8122 p->pfnTerminate = vmsvga3dBackTerminate;
8123 p->pfnReset = vmsvga3dBackReset;
8124 p->pfnQueryCaps = vmsvga3dBackQueryCaps;
8125 p->pfnChangeMode = vmsvga3dBackChangeMode;
8126 p->pfnCreateTexture = vmsvga3dBackCreateTexture;
8127 p->pfnSurfaceDestroy = vmsvga3dBackSurfaceDestroy;
8128 p->pfnSurfaceInvalidateImage = vmsvga3dBackSurfaceInvalidateImage;
8129 p->pfnSurfaceCopy = vmsvga3dBackSurfaceCopy;
8130 p->pfnSurfaceDMACopyBox = vmsvga3dBackSurfaceDMACopyBox;
8131 p->pfnSurfaceStretchBlt = vmsvga3dBackSurfaceStretchBlt;
8132 p->pfnUpdateHostScreenViewport = vmsvga3dBackUpdateHostScreenViewport;
8133 p->pfnDefineScreen = vmsvga3dBackDefineScreen;
8134 p->pfnDestroyScreen = vmsvga3dBackDestroyScreen;
8135 p->pfnSurfaceBlitToScreen = vmsvga3dBackSurfaceBlitToScreen;
8136 p->pfnSurfaceUpdateHeapBuffers = vmsvga3dBackSurfaceUpdateHeapBuffers;
8137 }
8138 }
8139 else
8140 {
8141 AssertFailed();
8142 rc = VERR_INVALID_PARAMETER;
8143 }
8144 }
8145 else
8146 rc = VERR_NOT_IMPLEMENTED;
8147 return rc;
8148}
8149
8150
8151extern VMSVGA3DBACKENDDESC const g_BackendDX =
8152{
8153 "DX",
8154 vmsvga3dBackQueryInterface
8155};
Note: See TracBrowser for help on using the repository browser.

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