VirtualBox

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

Last change on this file since 99471 was 99274, checked in by vboxsync, 21 months ago

Devices/Graphics: incorrect format

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