VirtualBox

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

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

Devices/Graphics: surface mapping cleanup and fixes: bugref:9830

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