VirtualBox

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

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

Devices/Graphics: blitter fix. bugref:9830

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

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