VirtualBox

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

Last change on this file since 99844 was 99831, checked in by vboxsync, 2 years ago

Devices/Graphics: RTV -> UAV fix copy paste bug

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

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