VirtualBox

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

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

Devices/Graphics: implemented some DXQuery commands; fixed various issues found by piglit: bugref:9830

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