VirtualBox

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

Last change on this file since 100108 was 100066, checked in by vboxsync, 23 months ago

Devices/Graphics: debug logging. bugref:9830

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