VirtualBox

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

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

Devices/Graphics: renamed a macro.

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

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